Beispiel #1
0
    def point_in_set(self, point):
        """
        Calculates if supplied ``point`` is contained in the uncertainty set. Returns True or False.

        Args:
            point: The point being checked for membership in the set.
                   The coordinates of the point should be supplied in the same order as the elements of ``uncertain_params``
                   that is to be supplied to the PyROS solve statement.
                   This point must match the dimension of the uncertain parameters of the set.
        """

        # === Ensure point is of correct dimensionality as the uncertain parameters
        if len(point) != self.dim:
            raise AttributeError("Point must have same dimensions as uncertain parameters.")

        m = ConcreteModel()
        the_params = []
        for i in range(self.dim):
            m.add_component("x_%s" % i, Var(initialize=point[i]))
            the_params.append(getattr(m, "x_%s" % i))

        # === Generate constraint for set
        set_constraint = self.set_as_constraint(uncertain_params=the_params)

        # === value() returns True if the constraint is satisfied, False else.
        is_in_set = all(value(con.expr) for con in set_constraint.values())

        return is_in_set
Beispiel #2
0
 def test_remove(self):
     model = self.model
     model = ConcreteModel()
     index = range(5)
     model.c = self._ctype(self._cdatatype(self._arg) for i in index)
     for i in index:
         cdata = model.c[0]
         self.assertEqual(cdata in model.c, True)
         model.c.remove(cdata)
         self.assertEqual(cdata in model.c, False)
 def test_remove(self):
     model = self.model
     model = ConcreteModel()
     index = range(5)
     model.c = self._ctype(self._cdatatype(self._arg) for i in index)
     for i in index:
         cdata = model.c[0]
         self.assertEqual(cdata in model.c, True)
         model.c.remove(cdata)
         self.assertEqual(cdata in model.c, False)
Beispiel #4
0
    def compile(self, start_time='20140101', recompile=False):
        """
        Compile the optimization problem

        :param start_time: Start time of this modesto instance. Either a pandas Timestamp object or a string of format
            'yyyymmdd'. Default '20140101'.
        :param recompile: True if model should be recompiled. If False, only mutable parameters are reloaded.
        :return:
        """

        # Set time
        if isinstance(start_time, str):
            self.start_time = pd.Timestamp(start_time)
        elif isinstance(start_time, pd.Timestamp):
            self.start_time = start_time
        else:
            raise IOError(
                "start_time specifier not recognized. Should be "
                "either string of format 'yyyymmdd' or pd.Timestamp.")

        # Check if not compiled already
        if self.compiled:
            if not recompile and not self.temperature_driven:
                self.logger.info(
                    'Model was already compiled. Only changing mutable parameters.'
                )

            else:
                self.model = ConcreteModel()
                self.compiled = False
                for comp in self.components:
                    self.components[comp].reinit()
                self.logger.info('Recompiling model.')

        # Check whether all necessary parameters are there
        self.check_data()
        self.update_time(self.start_time)

        # Components
        for name in self.get_edges():
            edge_obj = self.get_component(name=name)
            edge_obj.compile(self.model, start_time)

        nodes = self.get_nodes()

        for node in nodes:
            node_obj = self.get_component(name=node)
            node_obj.compile(self.model, start_time)

        if not self.compiled or recompile:
            self.__build_objectives()

        self.compiled = True  # Change compilation flag

        return
Beispiel #5
0
    def is_bounded(self, config):
        """
        Return True if the uncertainty set is bounded, else False.
        """
        # === Determine bounds on all uncertain params
        bounding_model = ConcreteModel()
        bounding_model.util = Block() # So that boundedness checks work for Cardinality and FactorModel sets
        bounding_model.uncertain_param_vars = IndexedVar(range(len(config.uncertain_params)), initialize=1)
        for idx, param in enumerate(config.uncertain_params):
            bounding_model.uncertain_param_vars[idx].value = param.value

        bounding_model.add_component("uncertainty_set_constraint",
                                     config.uncertainty_set.set_as_constraint(
                                         uncertain_params=bounding_model.uncertain_param_vars,
                                         model=bounding_model,
                                         config=config
                                     ))

        for idx, param in enumerate(list(bounding_model.uncertain_param_vars.values())):
            bounding_model.add_component("lb_obj_" + str(idx), Objective(expr=param, sense=minimize))
            bounding_model.add_component("ub_obj_" + str(idx), Objective(expr=param, sense=maximize))

        for o in bounding_model.component_data_objects(Objective):
            o.deactivate()

        for i in range(len(bounding_model.uncertain_param_vars)):
            for limit in ("lb", "ub"):
                getattr(bounding_model, limit + "_obj_" + str(i)).activate()
                res = config.global_solver.solve(bounding_model, tee=False)
                getattr(bounding_model, limit + "_obj_" + str(i)).deactivate()
                if not check_optimal_termination(res):
                    return False
        return True
 def test_setitem(self):
     model = self.model
     model = ConcreteModel()
     model.c = self._ctype()
     index = ['a', 1, None, (1,), (1,2)]
     for i in index:
         self.assertTrue(i not in model.c)
     for cnt, i in enumerate(index, 1):
         model.c[i] = self._cdatatype(self._arg)
         self.assertEqual(len(model.c), cnt)
         self.assertTrue(i in model.c)
Beispiel #7
0
 def test_setitem(self):
     model = self.model
     model = ConcreteModel()
     model.c = self._ctype()
     index = ['a', 1, None, (1, ), (1, 2)]
     for i in index:
         self.assertTrue(i not in model.c)
     for cnt, i in enumerate(index, 1):
         model.c[i] = self._cdatatype(self._arg())
         self.assertEqual(len(model.c), cnt)
         self.assertTrue(i in model.c)
Beispiel #8
0
def make_model_tri(n, small_val=1e-7, big_val=1e2):
    m = ConcreteModel()
    m.x = Var(range(n), initialize=0.5)

    def c_rule(m, i):
        return big_val*m.x[i-1] + small_val*m.x[i] + big_val*m.x[i+1] == 1
    
    m.c = Constraint(range(1,n-1), rule=c_rule)

    m.obj = Objective(expr=small_val*sum((m.x[i]-1)**2 for i in range(n)))

    return m
 def test_active(self):
     model = self.model
     model = ConcreteModel()
     model.c = self._ctype()
     self.assertEqual(model.c.active, True)
     model.c.deactivate()
     self.assertEqual(model.c.active, False)
     model.c.append(self._cdatatype(self._arg))
     self.assertEqual(model.c.active, True)
     model.c.deactivate()
     self.assertEqual(model.c.active, False)
     model.c.insert(0, self._cdatatype(self._arg))
     self.assertEqual(model.c.active, True)
Beispiel #10
0
 def test_active(self):
     model = self.model
     model = ConcreteModel()
     model.c = self._ctype()
     self.assertEqual(model.c.active, True)
     model.c.deactivate()
     self.assertEqual(model.c.active, False)
     model.c.append(self._cdatatype(self._arg))
     self.assertEqual(model.c.active, True)
     model.c.deactivate()
     self.assertEqual(model.c.active, False)
     model.c.insert(0, self._cdatatype(self._arg))
     self.assertEqual(model.c.active, True)
Beispiel #11
0
def add_bounds_for_uncertain_parameters(model, config):
    '''
    This function solves a set of optimization problems to determine bounds on the uncertain parameters
    given the uncertainty set description. These bounds will be added as additional constraints to the uncertainty_set_constr
    constraint. Should only be called once set_as_constraint() has been called on the separation_model object.
    :param separation_model: the model on which to add the bounds
    :param config: solver config
    :return:
    '''
    # === Determine bounds on all uncertain params
    uncertain_param_bounds = []
    bounding_model = ConcreteModel()
    bounding_model.util = Block()
    bounding_model.util.uncertain_param_vars = IndexedVar(
        model.util.uncertain_param_vars.index_set())
    for tup in model.util.uncertain_param_vars.items():
        bounding_model.util.uncertain_param_vars[tup[0]].value = tup[1].value

    bounding_model.add_component(
        "uncertainty_set_constraint",
        config.uncertainty_set.set_as_constraint(
            uncertain_params=bounding_model.util.uncertain_param_vars,
            model=bounding_model,
            config=config))

    for idx, param in enumerate(
            list(bounding_model.util.uncertain_param_vars.values())):
        bounding_model.add_component("lb_obj_" + str(idx),
                                     Objective(expr=param, sense=minimize))
        bounding_model.add_component("ub_obj_" + str(idx),
                                     Objective(expr=param, sense=maximize))

    for o in bounding_model.component_data_objects(Objective):
        o.deactivate()

    for i in range(len(bounding_model.util.uncertain_param_vars)):
        bounds = []
        for limit in ("lb", "ub"):
            getattr(bounding_model, limit + "_obj_" + str(i)).activate()
            res = config.global_solver.solve(bounding_model, tee=False)
            bounds.append(bounding_model.util.uncertain_param_vars[i].value)
            getattr(bounding_model, limit + "_obj_" + str(i)).deactivate()
        uncertain_param_bounds.append(bounds)

    # === Add bounds as constraints to uncertainty_set_constraint ConstraintList
    for idx, bound in enumerate(uncertain_param_bounds):
        model.util.uncertain_param_vars[idx].setlb(bound[0])
        model.util.uncertain_param_vars[idx].setub(bound[1])

    return
Beispiel #12
0
def initial_construct_master(model_data):
    """
    Constructs the iteration 0 master problem
    return: a MasterProblemData object containing the master_model object
    """
    m = ConcreteModel()
    m.scenarios = Block(NonNegativeIntegers, NonNegativeIntegers)

    master_data = MasterProblemData()
    master_data.original = model_data.working_model.clone()
    master_data.master_model = m
    master_data.timing = model_data.timing

    return master_data
Beispiel #13
0
    def __init__(self, pipe_model, graph, repr_days=None):
        """
        This class allows setting up optimization problems for district energy systems

        :param horizon: The horizon of the optimization problem, in seconds
        :param time_step: The time step between two points
        :param objective: String describing the objective of the optimization problem
        :param pipe_model: String describing the type of model to be used for the pipes
        :param graph: networkx object, describing the structure of the network
        :param repr_days: None if regular optimization. Dict of days of year
            mapped to representative days if used.
        """

        self.model = ConcreteModel(name=Modesto)

        self.results = None

        self.pipe_model = pipe_model
        if pipe_model == 'NodeMethod':
            self.temperature_driven = True
        else:
            self.temperature_driven = False

        self.allow_flow_reversal = True
        self.start_time = None
        if repr_days is not None:
            self.repr_days = {i: int(round(j)) for i, j in repr_days.items()}
        else:
            self.repr_days = repr_days

        self.graph = graph
        self.edges = {}
        self.nodes = {}
        self.components = {}
        self.params = self.create_params()

        self.logger = logging.getLogger('modesto.main.Modesto')

        self.build(graph)
        self.compiled = False

        self.objectives = {}
        self.act_objective = None
def two_objective_model():
    model = ConcreteModel()

    # Define variables
    model.x1 = Var(within=NonNegativeReals)
    model.x2 = Var(within=NonNegativeReals)

    # --------------------------------------
    #   Define the objective functions
    # --------------------------------------

    def objective1(model):
        return model.x1

    def objective2(model):
        return 3 * model.x1 + 4 * model.x2

    # --------------------------------------
    #   Define the regular constraints
    # --------------------------------------

    def constraint1(model):
        return model.x1 <= 20

    def constraint2(model):
        return model.x2 <= 40

    def constraint3(model):
        return 5 * model.x1 + 4 * model.x2 <= 200

    # --------------------------------------
    #   Add components to the model
    # --------------------------------------

    # Add the constraints to the model
    model.con1 = Constraint(rule=constraint1)
    model.con2 = Constraint(rule=constraint2)
    model.con3 = Constraint(rule=constraint3)

    # Add the objective functions to the model using ObjectiveList(). Note
    # that the first index is 1 instead of 0!
    model.obj_list = ObjectiveList()
    model.obj_list.add(expr=objective1(model), sense=maximize)
    model.obj_list.add(expr=objective2(model), sense=maximize)

    # By default deactivate all the objective functions
    for o in range(len(model.obj_list)):
        model.obj_list[o + 1].deactivate()

    return model
Beispiel #15
0
def make_model():
    m = ConcreteModel()
    m.time = ContinuousSet(bounds=(0, 10))
    m.space = ContinuousSet(bounds=(0, 5))
    m.set1 = Set(initialize=['a', 'b', 'c'])
    m.set2 = Set(initialize=['d', 'e', 'f'])
    m.fs = Block()

    m.fs.v0 = Var(m.space, initialize=1)

    @m.fs.Block()
    def b1(b):
        b.v = Var(m.time, m.space, initialize=1)
        b.dv = DerivativeVar(b.v, wrt=m.time, initialize=0)

        b.con = Constraint(m.time,
                           m.space,
                           rule=lambda b, t, x: b.dv[t, x] == 7 - b.v[t, x])
        # Inconsistent

        @b.Block(m.time)
        def b2(b, t):
            b.v = Var(initialize=2)

    @m.fs.Block(m.time, m.space)
    def b2(b, t, x):
        b.v = Var(m.set1, initialize=2)

        @b.Block(m.set1)
        def b3(b, c):
            b.v = Var(m.set2, initialize=3)

            @b.Constraint(m.set2)
            def con(b, s):
                return (5 * b.v[s] == m.fs.b2[m.time.first(),
                                              m.space.first()].v[c])
                # inconsistent

    @m.fs.Constraint(m.time)
    def con1(fs, t):
        return fs.b1.v[t, m.space.last()] == 5

    # Will be inconsistent

    @m.fs.Constraint(m.space)
    def con2(fs, x):
        return fs.b1.v[m.time.first(), x] == fs.v0[x]

    # will be consistent

    disc = TransformationFactory('dae.collocation')
    disc.apply_to(m, wrt=m.time, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')
    disc.apply_to(m, wrt=m.space, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')

    return m
Beispiel #16
0
def make_model_2():
    m = ConcreteModel()
    m.x = Var(initialize=0.1, bounds=(0, 1))
    m.y = Var(initialize=0.1, bounds=(0, 1))
    m.obj = Objective(expr=-m.x**2 - m.y**2)
    m.c = Constraint(expr=m.y <= pe.exp(-m.x))
    return m
Beispiel #17
0
    def is_empty_intersection(self, uncertain_params, nlp_solver):
        """
        Determine if intersection is empty

        Args:
            uncertain_params: list of uncertain parameters
            nlp_solver: a Pyomo Solver object for solving NLPs
        """

        # === Non-emptiness check for the set intersection
        is_empty_intersection = True
        if any(a_set.type == "discrete" for a_set in self.all_sets):
            disc_sets = (a_set for a_set in self.all_sets if a_set.type == "discrete")
            disc_set = min(disc_sets, key=lambda x: len(x.scenarios))  # minimum set of scenarios
            # === Ensure there is at least one scenario from this discrete set which is a member of all other sets
            for scenario in disc_set.scenarios:
                if all(a_set.point_in_set(point=scenario) for a_set in self.all_sets):
                    is_empty_intersection = False
                    break
        else:
            # === Compile constraints and solve NLP
            m = ConcreteModel()
            m.obj = Objective(expr=0) # dummy objective required if using baron
            m.param_vars = Var(uncertain_params.index_set())
            for a_set in self.all_sets:
                m.add_component(a_set.type + "_constraints", a_set.set_as_constraint(uncertain_params=m.param_vars))
            try:
                res = nlp_solver.solve(m)
            except:
                raise ValueError("Solver terminated with an error while checking set intersection non-emptiness.")
            if check_optimal_termination(res):
                is_empty_intersection = False
        return is_empty_intersection
def two_kp_model(type):
    model = ConcreteModel()

    # Define input files
    xlsx = pd.ExcelFile(
        f"{Path(__file__).parent.absolute()}/input/{type}.xlsx",
        engine="openpyxl")
    a = pd.read_excel(xlsx, index_col=0, sheet_name="a").to_numpy()
    b = pd.read_excel(xlsx, index_col=0, sheet_name="b").to_numpy()
    c = pd.read_excel(xlsx, index_col=0, sheet_name="c").to_numpy()

    # Define variables
    model.ITEMS = Set(initialize=range(len(a[0])))
    model.x = Var(model.ITEMS, within=Binary)

    # --------------------------------------
    #   Define the objective functions
    # --------------------------------------

    def objective1(model):
        return sum(c[0][i] * model.x[i] for i in model.ITEMS)

    def objective2(model):
        return sum(c[1][i] * model.x[i] for i in model.ITEMS)

    # --------------------------------------
    #   Define the regular constraints
    # --------------------------------------

    def constraint1(model):
        return sum(a[0][i] * model.x[i] for i in model.ITEMS) <= b[0][0]

    def constraint2(model):
        return sum(a[1][i] * model.x[i] for i in model.ITEMS) <= b[1][0]

    # --------------------------------------
    #   Add components to the model
    # --------------------------------------

    # Add the constraints to the model
    model.con1 = Constraint(rule=constraint1)
    model.con2 = Constraint(rule=constraint2)

    # Add the objective functions to the model using ObjectiveList(). Note
    # that the first index is 1 instead of 0!
    model.obj_list = ObjectiveList()
    model.obj_list.add(expr=objective1(model), sense=maximize)
    model.obj_list.add(expr=objective2(model), sense=maximize)

    # By default deactivate all the objective functions
    for o in range(len(model.obj_list)):
        model.obj_list[o + 1].deactivate()

    return model
Beispiel #19
0
def make_model():
    m = ConcreteModel()
    m.x = Var([1,2,3], initialize=0)
    m.f = Var([1,2,3], initialize=0)
    m.F = Var(initialize=0)
    m.f[1].fix(1)
    m.f[2].fix(2)

    m.sum_con = Constraint(expr= 
            (1 == m.x[1] + m.x[2] + m.x[3]))
    def bilin_rule(m, i):
        return m.F*m.x[i] == m.f[i]
    m.bilin_con = Constraint([1,2,3], rule=bilin_rule)

    m.obj = Objective(expr=m.F**2)

    return m
Beispiel #20
0
def convert(options=Bunch(), parser=None, model_format=None):
    global _format
    if not model_format is None:
        _format = model_format
    #
    # Import plugins
    #
    import pyomo.environ

    if options.model.save_file is None:
        if _format == ProblemFormat.cpxlp:
            options.model.save_file = 'unknown.lp'
        else:
            options.model.save_file = 'unknown.' + str(_format)
    options.model.save_format = _format

    data = Bunch(options=options)

    model_data = None
    try:
        pyomo.scripting.util.setup_environment(data)

        pyomo.scripting.util.apply_preprocessing(data, parser=parser)

        if data.error:
            return Bunch()

        model_data = pyomo.scripting.util.create_model(data)

        model_data.options = options
    except:

        # TBD: I should be able to call this function in the case of
        #      an exception to perform cleanup. However, as it stands
        #      calling finalize with its default keyword value for
        #      model(=None) results in an a different error related to
        #      task port values.  Not sure how to interpret that.
        pyomo.scripting.util.finalize(data,
                                      model=ConcreteModel(),
                                      instance=None,
                                      results=None)
        raise

    else:

        pyomo.scripting.util.finalize(data, model=model_data.model)

    return model_data
Beispiel #21
0
 def _dualize(self, block, unfixed=[]):
     """
     Generate the dual of a block
     """
     #
     # Collect linear terms from the block
     #
     A, b_coef, c_rhs, c_sense, d_sense, vnames, cnames, v_domain = collect_linear_terms(
         block, unfixed)
     #
     # Construct the block
     #
     if isinstance(block, Model):
         dual = ConcreteModel()
     else:
         dual = Block()
     for v, is_indexed in vnames:
         if is_indexed:
             setattr(dual, v + '_Index', Set(dimen=None))
             setattr(dual, v, Var(getattr(dual, v + '_Index')))
         else:
             setattr(dual, v, Var())
     for cname, is_indexed in cnames:
         if is_indexed:
             setattr(dual, cname + '_Index', Set(dimen=None))
             setattr(dual, cname,
                     Constraint(getattr(dual, cname + '_Index')))
             setattr(dual, cname + '_lower_',
                     Var(getattr(dual, cname + '_Index')))
             setattr(dual, cname + '_upper_',
                     Var(getattr(dual, cname + '_Index')))
         else:
             setattr(dual, cname, Constraint())
             setattr(dual, cname + '_lower_', Var())
             setattr(dual, cname + '_upper_', Var())
     dual.construct()
     #
     # Add variables
     #
     # TODO: revisit this hack.  We shouldn't be calling
     # _getitem_when_not_present()
     #
     for name, ndx in b_coef:
         v = getattr(dual, name)
         if not ndx in v:
             v._getitem_when_not_present(ndx)
     #
     # Construct the objective
     #
     if d_sense == minimize:
         dual.o = Objective(expr=sum(-b_coef[name, ndx] *
                                     getattr(dual, name)[ndx]
                                     for name, ndx in b_coef),
                            sense=d_sense)
     else:
         dual.o = Objective(expr=sum(b_coef[name, ndx] *
                                     getattr(dual, name)[ndx]
                                     for name, ndx in b_coef),
                            sense=d_sense)
     #
     # Construct the constraints
     #
     for cname in A:
         c = getattr(dual, cname)
         c_index = getattr(dual, cname +
                           "_Index") if c.is_indexed() else None
         for ndx, terms in iteritems(A[cname]):
             if not c_index is None and not ndx in c_index:
                 c_index.add(ndx)
             expr = 0
             for term in terms:
                 v = getattr(dual, term.var)
                 if not term.ndx in v:
                     v.add(term.ndx)
                 expr += term.coef * v[term.ndx]
             if not (cname, ndx) in c_rhs:
                 c_rhs[cname, ndx] = 0.0
             if c_sense[cname, ndx] == 'e':
                 c.add(ndx, expr - c_rhs[cname, ndx] == 0)
             elif c_sense[cname, ndx] == 'l':
                 c.add(ndx, expr - c_rhs[cname, ndx] <= 0)
             else:
                 c.add(ndx, expr - c_rhs[cname, ndx] >= 0)
         for (name, ndx), domain in iteritems(v_domain):
             v = getattr(dual, name)
             flag = type(ndx) is tuple and (ndx[-1] == 'lb'
                                            or ndx[-1] == 'ub')
             if domain == 1:
                 if flag:
                     v[ndx].domain = NonNegativeReals
                 else:
                     v.domain = NonNegativeReals
             elif domain == -1:
                 if flag:
                     v[ndx].domain = NonPositiveReals
                 else:
                     v.domain = NonPositiveReals
             else:
                 if flag:
                     # TODO: verify that this case is possible
                     v[ndx].domain = Reals
                 else:
                     v.domain = Reals
     return dual
Beispiel #22
0
        return m.Vm[i, k] == m.x[i, k] * ((1/2288) * 0.2685**(1 + (1 - m.T[i, k]/512.4)**0.2453)) + \
               (1 - m.x[i, k]) * ((1/1235) * 0.27136**(1 + (1 - m.T[i, k]/536.4)**0.24))
    else:
        return Constraint.Skip


# Initial conditions for the given noisy-filter
def acm(m, k):
    return m.M[0, k] == m.M_ic[k]


def acx(m, k):
    return m.x[0, k] == m.x_ic[k]

# ---------------------------------------------------------------------------------------------------------------------
mod = ConcreteModel()

mod.t = ContinuousSet(bounds=(0, 1))
mod.Ntray = Ntray = 42

mod.tray = Set(initialize=[i for i in range(1, mod.Ntray + 1)])
mod.feed = Param(mod.tray,
                  initialize=lambda m, k: 57.5294 if k == 21 else 0.0,
                  mutable=True)

mod.xf = Param(initialize=0.32, mutable=True)  # feed mole fraction
mod.hf = Param(initialize=9081.3)  # feed enthalpy

mod.hlm0 = Param(initialize=2.6786e-04)
mod.hlma = Param(initialize=-0.14779)
mod.hlmb = Param(initialize=97.4289)
Beispiel #23
0
 def _dualize(self, block, unfixed=[]):
     """
     Generate the dual of a block
     """ 
     #
     # Collect linear terms from the block
     #
     A, b_coef, c_rhs, c_sense, d_sense, vnames, cnames, v_domain = collect_linear_terms(block, unfixed)
     #
     # Construct the block
     #
     if isinstance(block, Model):
         dual = ConcreteModel()
     else:
         dual = Block()
     for v, is_indexed in vnames:
         if is_indexed:
             setattr(dual, v+'_Index', Set(dimen=None))
             setattr(dual, v, Var(getattr(dual, v+'_Index')))
         else:
             setattr(dual, v, Var())
     for cname, is_indexed in cnames:
         if is_indexed:
             setattr(dual, cname+'_Index', Set(dimen=None))
             setattr(dual, cname, Constraint(getattr(dual, cname+'_Index')))
             setattr(dual, cname+'_lower_', Var(getattr(dual, cname+'_Index')))
             setattr(dual, cname+'_upper_', Var(getattr(dual, cname+'_Index')))
         else:
             setattr(dual, cname, Constraint())
             setattr(dual, cname+'_lower_', Var())
             setattr(dual, cname+'_upper_', Var())
     dual.construct()
     #
     # Add variables
     #
     # TODO: revisit this hack.  We shouldn't be calling _default()
     #
     for name, ndx in b_coef:
         v = getattr(dual, name)
         if not ndx in v:
             v._default(ndx)    
     #
     # Construct the objective
     #
     if d_sense == minimize:
         dual.o = Objective(expr=sum(- b_coef[name,ndx]*getattr(dual,name)[ndx] for name,ndx in b_coef), sense=d_sense)
     else:
         dual.o = Objective(expr=sum(b_coef[name,ndx]*getattr(dual,name)[ndx] for name,ndx in b_coef), sense=d_sense)
     #
     # Construct the constraints
     #
     for cname in A:
         c = getattr(dual, cname)
         c_index = getattr(dual, cname+"_Index") if c.is_indexed() else None
         for ndx,terms in iteritems(A[cname]):
             if not c_index is None and not ndx in c_index:
                 c_index.add(ndx)
             expr = 0
             for term in terms:
                 v = getattr(dual,term.var)
                 if not term.ndx in v:
                     v.add(term.ndx)
                 expr += term.coef * v[term.ndx]
             if not (cname, ndx) in c_rhs:
                 c_rhs[cname, ndx] = 0.0
             if c_sense[cname,ndx] == 'e':
                 c.add(ndx, expr - c_rhs[cname,ndx] == 0)
             elif c_sense[cname,ndx] == 'l':
                 c.add(ndx, expr - c_rhs[cname,ndx] <= 0)
             else:
                 c.add(ndx, expr - c_rhs[cname,ndx] >= 0)
         for (name, ndx), domain in iteritems(v_domain):
             v = getattr(dual, name)
             flag = type(ndx) is tuple and (ndx[-1] == 'lb' or ndx[-1] == 'ub')
             if domain == 1:
                 if flag:
                     v[ndx].domain = NonNegativeReals
                 else:
                     v.domain = NonNegativeReals
             elif domain == -1:
                 if flag:
                     v[ndx].domain = NonPositiveReals
                 else:
                     v.domain = NonPositiveReals
             else:
                 if flag:
                     # TODO: verify that this case is possible
                     v[ndx].domain = Reals
                 else:
                     v.domain = Reals
     return dual
Beispiel #24
0
    def _dualize(self, block, unfixed=[]):
        """
        Generate the dual of a block
        """
        #
        # Collect linear terms from the block
        #
        A, b_coef, c_rhs, c_sense, d_sense, vnames, cnames, v_domain = collect_linear_terms(block, unfixed)
        ##print(A)
        ##print(vnames)
        ##print(cnames)
        ##print(list(A.keys()))
        ##print("---")
        ##print(A.keys())
        ##print(c_sense)
        ##print(c_rhs)
        #
        # Construct the block
        #
        if isinstance(block, Model):
            dual = ConcreteModel()
        else:
            dual = Block()
        dual.construct()
        _vars = {}
        def getvar(name, ndx=None):
            v = _vars.get((name,ndx), None)
            if v is None:
                v = Var()
                if ndx is None:
                    v_name = name
                elif type(ndx) is tuple:
                    v_name = "%s[%s]" % (name, ','.join(map(str,ndx)))
                else:
                    v_name = "%s[%s]" % (name, str(ndx))
                setattr(dual, v_name, v)
                _vars[name,ndx] = v
            return v
        #
        # Construct the objective
        #
        if d_sense == minimize:
            dual.o = Objective(expr=sum(- b_coef[name,ndx]*getvar(name,ndx) for name,ndx in b_coef), sense=d_sense)
        else:
            dual.o = Objective(expr=sum(b_coef[name,ndx]*getvar(name,ndx) for name,ndx in b_coef), sense=d_sense)
        #
        # Construct the constraints
        #
        for cname in A:
            for ndx, terms in iteritems(A[cname]):
                expr = 0
                for term in terms:
                    expr += term.coef * getvar(term.var, term.ndx)
                if not (cname, ndx) in c_rhs:
                    c_rhs[cname, ndx] = 0.0
                if c_sense[cname, ndx] == 'e':
                    e = expr - c_rhs[cname,ndx] == 0
                elif c_sense[cname, ndx] == 'l':
                    e = expr - c_rhs[cname,ndx] <= 0
                else:
                    e = expr - c_rhs[cname,ndx] >= 0
                c = Constraint(expr=e)
                if ndx is None:
                    c_name = cname
                elif type(ndx) is tuple:
                    c_name = "%s[%s]" % (cname, ','.join(map(str,ndx)))
                else:
                    c_name = "%s[%s]" % (cname, str(ndx))
                setattr(dual, c_name, c)
            #
            for (name, ndx), domain in iteritems(v_domain):
                v = getvar(name, ndx)
                flag = type(ndx) is tuple and (ndx[-1] == 'lb' or ndx[-1] == 'ub')
                if domain == 1:
                    v.domain = NonNegativeReals
                elif domain == -1:
                    v.domain = NonPositiveReals
                else:
                    # TODO: verify that this case is possible
                    v.domain = Reals

        return dual
Beispiel #25
0
def solveropfnlp_2(ppc, solver="ipopt"):
    if solver == "ipopt":
        opt = SolverFactory("ipopt", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/ipopt-linux64/ipopt")
    if solver == "bonmin":
        opt = SolverFactory("bonmin", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/bonmin-linux64/bonmin")
    if solver == "knitro":
        opt = SolverFactory("knitro", executable="D:/ICT/Artelys/Knitro 10.2.1/knitroampl/knitroampl")

    ppc = ext2int(ppc)      # convert to continuous indexing starting from 0

    # Gather information about the system
    # =============================================================
    baseMVA, bus, gen, branch = \
        ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc["branch"]

    nb = bus.shape[0]       # number of buses
    ng = gen.shape[0]       # number of generators
    nl = branch.shape[0]    # number of lines

    # generator buses
    gb = tolist(np.array(gen[:, GEN_BUS]).astype(int))

    sb = find((bus[:, BUS_TYPE] == REF))    # slack bus index
    fr = branch[:, F_BUS].astype(int)       # from bus indices
    to = branch[:, T_BUS].astype(int)       # to bus indices

    tr = branch[:, TAP]     # transformation ratios
    tr[find(tr == 0)] = 1   # set to 1 transformation ratios that are 0

    r = branch[:, BR_R]     # branch resistances
    x = branch[:, BR_X]     # branch reactances
    b = branch[:, BR_B]     # branch susceptances

    start_time = time.clock()

    # Admittance matrix computation
    # =============================================================
    y = makeYbus(baseMVA, bus, branch)[0]   # admittance matrix

    yk = 1./(r+x*1j)                        # branch admittance
    yft = yk + 0.5j*b                       # branch admittance + susceptance
    gk = yk.real                            # branch resistance
    yk = yk/tr                              # include /tr in yk

    # Optimization
    # =============================================================
    branch[find(branch[:, RATE_A] == 0), RATE_A] = 9999     # set undefined Sflow limit to 9999
    Smax = branch[:, RATE_A] / baseMVA                      # Max. Sflow

    # Power demand parameters
    Pd = bus[:, PD] / baseMVA
    Qd = bus[:, QD] / baseMVA

    # Max and min Pg and Qg
    Pg_max = zeros(nb)
    Pg_max[gb] = gen[:, PMAX] / baseMVA
    Pg_min = zeros(nb)
    Pg_min[gb] = gen[:, PMIN] / baseMVA
    Qg_max = zeros(nb)
    Qg_max[gb] = gen[:, QMAX] / baseMVA
    Qg_min = zeros(nb)
    Qg_min[gb] = gen[:, QMIN] / baseMVA

    # Vmax and Vmin vectors
    Vmax = bus[:, VMAX]
    Vmin = bus[:, VMIN]

    vm = bus[:, VM]
    va = bus[:, VA]*pi/180

    # create a new optimization model
    model = ConcreteModel()

    # Define sets
    # ------------
    model.bus = Set(ordered=True, initialize=range(nb))     # Set of all buses
    model.gen = Set(ordered=True, initialize=gb)                # Set of buses with generation
    model.line = Set(ordered=True, initialize=range(nl))    # Set of all lines

    # Define variables
    # -----------------
    # Voltage magnitudes vector (vm)
    model.vm = Var(model.bus)

    # Voltage angles vector (va)
    model.va = Var(model.bus)

    # Reactive power generation, synchronous machines(SM) (Qg)
    model.Qg = Var(model.gen)
    Qg0 = zeros(nb)
    Qg0[gb] = gen[:, QG]/baseMVA

    # Active power generation, synchronous machines(SM) (Pg)
    model.Pg = Var(model.gen)
    Pg0 = zeros(nb)
    Pg0[gb] = gen[:, PG] / baseMVA

    # Active and reactive power from at all branches
    model.Pf = Var(model.line)
    model.Qf = Var(model.line)

    # Active and reactive power to at all branches
    model.Pt = Var(model.line)
    model.Qt = Var(model.line)

    # Warm start the problem
    # ------------------------
    for i in range(nb):
        model.vm[i] = vm[i]
        model.va[i] = va[i]
        if i in gb:
            model.Pg[i] = Pg0[i]
            model.Qg[i] = Qg0[i]
    for i in range(nl):
        model.Pf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.cos(-ang(yft[i])) -\
                      vm[fr[i]] * vm[to[i]] * abs(yk[i]) * np.cos(va[fr[i]] - va[to[i]] - ang(yk[i]))
        model.Qf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.sin(-ang(yft[i])) -\
                      vm[fr[i]] * vm[to[i]] * abs(yk[i]) * np.sin(va[fr[i]] - va[to[i]] - ang(yk[i]))
        model.Pt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) -\
                      vm[to[i]] * vm[fr[i]] * abs(yk[i]) * np.cos(va[to[i]] - va[fr[i]] - ang(yk[i]))
        model.Qt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) -\
                      vm[to[i]] * vm[fr[i]] * abs(yk[i]) * np.sin(va[to[i]] - va[fr[i]] - ang(yk[i]))

    # Define constraints
    # ----------------------------

    # Equalities:
    # ------------

    # Active power flow equalities
    def powerflowact(model, i):
        if i in gb:
            return model.Pg[i]-Pd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) *
                                            cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb))
        else:
            return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * cos(model.va[i] - model.va[j] -
                                                                  ang(y[i, j])) for j in range(nb)) == -Pd[i]

    model.const1 = Constraint(model.bus, rule=powerflowact)

    # Reactive power flow equalities
    def powerflowreact(model, i):
        if i in gb:
            return model.Qg[i]-Qd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) *
                                            sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb))
        else:
            return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * sin(model.va[i] - model.va[j] -
                                                                  ang(y[i, j])) for j in range(nb)) == -Qd[i]

    model.const2 = Constraint(model.bus, rule=powerflowreact)

    # Active power from
    def pfrom(model, i):
        return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.cos(-ang(yft[i])) - \
                              model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \
                              cos(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))

    model.const3 = Constraint(model.line, rule=pfrom)

    # Reactive power from
    def qfrom(model, i):
        return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.sin(-ang(yft[i])) - \
                              model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \
                              sin(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))

    model.const4 = Constraint(model.line, rule=qfrom)

    # Active power to
    def pto(model, i):
        return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \
                              model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \
                              cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))

    model.const5 = Constraint(model.line, rule=pto)

    # Reactive power to
    def qto(model, i):
        return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \
                              model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \
                              sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))

    model.const6 = Constraint(model.line, rule=qto)

    # Slack bus phase angle
    model.const7 = Constraint(expr=model.va[sb[0]] == 0)

    # Inequalities:
    # ----------------

    # Active power generator limits Pg_min <= Pg <= Pg_max
    def genplimits(model, i):
        return Pg_min[i] <= model.Pg[i] <= Pg_max[i]

    model.const8 = Constraint(model.gen, rule=genplimits)

    # Reactive power generator limits Qg_min <= Qg <= Qg_max
    def genqlimits(model, i):
        return Qg_min[i] <= model.Qg[i] <= Qg_max[i]

    model.const9 = Constraint(model.gen, rule=genqlimits)

    # Voltage constraints ( Vmin <= V <= Vmax )
    def vlimits(model, i):
        return Vmin[i] <= model.vm[i] <= Vmax[i]

    model.const10 = Constraint(model.bus, rule=vlimits)

    # Sfrom line limit
    def sfrommax(model, i):
        return model.Pf[i]**2 + model.Qf[i]**2 <= Smax[i]**2

    model.const11 = Constraint(model.line, rule=sfrommax)

    # Sto line limit
    def stomax(model, i):
        return model.Pt[i]**2 + model.Qt[i]**2 <= Smax[i]**2

    model.const12 = Constraint(model.line, rule=stomax)

    # Set objective function
    # ------------------------
    def obj_fun(model):
        return sum(gk[i] * ((model.vm[fr[i]] / tr[i])**2 + model.vm[to[i]]**2 -
                         2/tr[i] * model.vm[fr[i]] * model.vm[to[i]] *
                         cos(model.va[fr[i]] - model.va[to[i]])) for i in range(nl))

    model.obj = Objective(rule=obj_fun, sense=minimize)

    mt = time.clock() - start_time                  # Modeling time

    # Execute solve command with the selected solver
    # ------------------------------------------------
    start_time = time.clock()
    results = opt.solve(model, tee=True)
    et = time.clock() - start_time                  # Elapsed time
    print(results)

    # Update the case info with the optimized variables
    # ==================================================
    for i in range(nb):
        bus[i, VM] = model.vm[i].value              # Bus voltage magnitudes
        bus[i, VA] = model.va[i].value*180/pi       # Bus voltage angles
    # Include Pf - Qf - Pt - Qt in the branch matrix
    branchsol = zeros((nl, 17))
    branchsol[:, :-4] = branch
    for i in range(nl):
        branchsol[i, PF] = model.Pf[i].value * baseMVA
        branchsol[i, QF] = model.Qf[i].value * baseMVA
        branchsol[i, PT] = model.Pt[i].value * baseMVA
        branchsol[i, QT] = model.Qt[i].value * baseMVA
    # Update gen matrix variables
    for i in range(ng):
        gen[i, PG] = model.Pg[gb[i]].value * baseMVA
        gen[i, QG] = model.Qg[gb[i]].value * baseMVA
        gen[i, VG] = bus[gb[i], VM]
    # Convert to external (original) numbering and save case results
    ppc = int2ext(ppc)
    ppc['bus'][:, 1:] = bus[:, 1:]
    branchsol[:, 0:2] = ppc['branch'][:, 0:2]
    ppc['branch'] = branchsol
    ppc['gen'][:, 1:] = gen[:, 1:]
    ppc['obj'] = value(obj_fun(model))
    ppc['ploss'] = value(obj_fun(model)) * baseMVA
    ppc['et'] = et
    ppc['mt'] = mt
    ppc['success'] = 1

    # ppc solved case is returned
    return ppc
def unit_commitment_model():
    model = ConcreteModel()

    # Define input files
    xlsx = pd.ExcelFile(
        f"{Path(__file__).parent.absolute()}/input/unit_commitment.xlsx",
        engine="openpyxl",
    )
    system_demand = Helper.read_excel(xlsx, "SystemDemand")
    storage_systems = Helper.read_excel(xlsx, "StorageSystems")
    generators = Helper.read_excel(xlsx, "Generators")
    generator_step_size = Helper.read_excel(xlsx, "GeneratorStepSize")
    generator_step_cost = Helper.read_excel(xlsx, "GeneratorStepCost")
    pv_generation = Helper.read_excel(xlsx, "PVGeneration")

    # Define sets
    model.T = Set(ordered=True, initialize=system_demand.index)
    model.I = Set(ordered=True, initialize=generators.index)
    model.F = Set(ordered=True, initialize=generator_step_size.columns)
    model.S = Set(ordered=True, initialize=storage_systems.index)

    # Define parameters
    model.Pmax = Param(model.I, within=NonNegativeReals, mutable=True)
    model.Pmin = Param(model.I, within=NonNegativeReals, mutable=True)

    model.RU = Param(model.I, within=NonNegativeReals, mutable=True)
    model.RD = Param(model.I, within=NonNegativeReals, mutable=True)
    model.SUC = Param(model.I, within=NonNegativeReals, mutable=True)
    model.SDC = Param(model.I, within=NonNegativeReals, mutable=True)
    model.Pini = Param(model.I, within=NonNegativeReals, mutable=True)
    model.uini = Param(model.I, within=Binary, mutable=True)
    model.C = Param(model.I, model.F, within=NonNegativeReals, mutable=True)
    model.B = Param(model.I, model.F, within=NonNegativeReals, mutable=True)
    model.SystemDemand = Param(model.T, within=NonNegativeReals, mutable=True)
    model.Emissions = Param(model.I, within=NonNegativeReals, mutable=True)

    model.PV = Param(model.T, within=NonNegativeReals, mutable=True)

    model.ESS_Pmax = Param(model.S, within=NonNegativeReals, mutable=True)
    model.ESS_SOEmax = Param(model.S, within=NonNegativeReals, mutable=True)
    model.ESS_SOEini = Param(model.S, within=NonNegativeReals, mutable=True)
    model.ESS_Eff = Param(model.S, within=NonNegativeReals, mutable=True)

    # Give values to parameters of the generators
    for i in model.I:
        model.Pmin[i] = generators.loc[i, "Pmin"]
        model.Pmax[i] = generators.loc[i, "Pmax"]
        model.RU[i] = generators.loc[i, "RU"]
        model.RD[i] = generators.loc[i, "RD"]
        model.SUC[i] = generators.loc[i, "SUC"]
        model.SDC[i] = generators.loc[i, "SDC"]
        model.Pini[i] = generators.loc[i, "Pini"]
        model.uini[i] = generators.loc[i, "uini"]
        model.Emissions[i] = generators.loc[i, "Emissions"]
        for f in model.F:
            model.B[i, f] = generator_step_size.loc[i, f]
            model.C[i, f] = generator_step_cost.loc[i, f]

    # Add system demand and PV generation
    for t in model.T:
        model.SystemDemand[t] = system_demand.loc[t, "SystemDemand"]
        model.PV[t] = pv_generation.loc[t, "PVGeneration"]

    # Give values to ESS parameters
    for s in model.S:
        model.ESS_Pmax[s] = storage_systems.loc[s, "Power"]
        model.ESS_SOEmax[s] = storage_systems.loc[s, "Energy"]
        model.ESS_SOEini[s] = storage_systems.loc[s, "SOEini"]
        model.ESS_Eff[s] = storage_systems.loc[s, "Eff"]

    # Define decision variables
    model.P = Var(model.I, model.T, within=NonNegativeReals)
    model.Pres = Var(model.T, within=NonNegativeReals)
    model.b = Var(model.I, model.F, model.T, within=NonNegativeReals)
    model.u = Var(model.I, model.T, within=Binary)
    model.CSU = Var(model.I, model.T, within=NonNegativeReals)
    model.CSD = Var(model.I, model.T, within=NonNegativeReals)

    model.SOE = Var(model.S, model.T, within=NonNegativeReals)
    model.Pch = Var(model.S, model.T, within=NonNegativeReals)
    model.Pdis = Var(model.S, model.T, within=NonNegativeReals)
    model.u_ess = Var(model.S, model.T, within=Binary)

    # --------------------------------------
    #   Define the objective functions
    # --------------------------------------

    def cost_objective(model):
        return sum(
            sum(
                sum(model.C[i, f] * model.b[i, f, t]
                    for f in model.F) + model.CSU[i, t] + model.CSD[i, t]
                for i in model.I) for t in model.T)

    def emissions_objective(model):
        return sum(
            sum(model.P[i, t] * model.Emissions[i] for i in model.I)
            for t in model.T)

    def unmet_objective(model):
        return sum(model.Pres[t] for t in model.T)

    # --------------------------------------
    #   Define the regular constraints
    # --------------------------------------

    def power_decomposition_rule1(model, i, t):
        return model.P[i, t] == sum(model.b[i, f, t] for f in model.F)

    def power_decomposition_rule2(model, i, f, t):
        return model.b[i, f, t] <= model.B[i, f]

    def power_min_rule(model, i, t):
        return model.P[i, t] >= model.Pmin[i] * model.u[i, t]

    def power_max_rule(model, i, t):
        return model.P[i, t] <= model.Pmax[i] * model.u[i, t]

    def ramp_up_rule(model, i, t):
        if model.T.ord(t) == 1:
            return model.P[i, t] - model.Pini[i] <= 60 * model.RU[i]

        if model.T.ord(t) > 1:
            return model.P[i, t] - model.P[i,
                                           model.T.prev(t)] <= 60 * model.RU[i]

    def ramp_down_rule(model, i, t):
        if model.T.ord(t) == 1:
            return (model.Pini[i] - model.P[i, t]) <= 60 * model.RD[i]

        if model.T.ord(t) > 1:
            return (model.P[i, model.T.prev(t)] -
                    model.P[i, t]) <= 60 * model.RD[i]

    def start_up_cost(model, i, t):
        if model.T.ord(t) == 1:
            return model.CSU[i, t] >= model.SUC[i] * (model.u[i, t] -
                                                      model.uini[i])

        if model.T.ord(t) > 1:
            return model.CSU[i, t] >= model.SUC[i] * (
                model.u[i, t] - model.u[i, model.T.prev(t)])

    def shut_down_cost(model, i, t):
        if model.T.ord(t) == 1:
            return model.CSD[i, t] >= model.SDC[i] * (model.uini[i] -
                                                      model.u[i, t])

        if model.T.ord(t) > 1:
            return model.CSD[i, t] >= model.SDC[i] * (
                model.u[i, model.T.prev(t)] - model.u[i, t])

    def ESS_SOEupdate(model, s, t):
        if model.T.ord(t) == 1:
            return (model.SOE[s, t] == model.ESS_SOEini[s] +
                    model.ESS_Eff[s] * model.Pch[s, t] -
                    model.Pdis[s, t] / model.ESS_Eff[s])

        if model.T.ord(t) > 1:
            return (model.SOE[s, t] == model.SOE[s, model.T.prev(t)] +
                    model.ESS_Eff[s] * model.Pch[s, t] -
                    model.Pdis[s, t] / model.ESS_Eff[s])

    def ESS_SOElimit(model, s, t):
        return model.SOE[s, t] <= model.ESS_SOEmax[s]

    def ESS_Charging(model, s, t):
        return model.Pch[s, t] <= model.ESS_Pmax[s] * model.u_ess[s, t]

    def ESS_Discharging(model, s, t):
        return model.Pdis[s, t] <= model.ESS_Pmax[s] * (1 - model.u_ess[s, t])

    def Balance(model, t):
        return model.PV[t] + sum(model.P[i, t] for i in model.I) + sum(
            model.Pdis[s, t]
            for s in model.S) == model.SystemDemand[t] - model.Pres[t] + sum(
                model.Pch[s, t] for s in model.S)

    def Pres_max(model, t):
        return model.Pres[t] <= 0.1 * model.SystemDemand[t]

    # --------------------------------------
    #   Add components to the model
    # --------------------------------------

    # Add the constraints to the model
    model.power_decomposition_rule1 = Constraint(
        model.I, model.T, rule=power_decomposition_rule1)
    model.power_decomposition_rule2 = Constraint(
        model.I, model.F, model.T, rule=power_decomposition_rule2)
    model.power_min_rule = Constraint(model.I, model.T, rule=power_min_rule)
    model.power_max_rule = Constraint(model.I, model.T, rule=power_max_rule)
    model.start_up_cost = Constraint(model.I, model.T, rule=start_up_cost)
    model.shut_down_cost = Constraint(model.I, model.T, rule=shut_down_cost)
    model.ConSOEUpdate = Constraint(model.S, model.T, rule=ESS_SOEupdate)
    model.ConCharging = Constraint(model.S, model.T, rule=ESS_Charging)
    model.ConDischarging = Constraint(model.S, model.T, rule=ESS_Discharging)
    model.ConSOElimit = Constraint(model.S, model.T, rule=ESS_SOElimit)
    model.ConGenUp = Constraint(model.I, model.T, rule=ramp_up_rule)
    model.ConGenDown = Constraint(model.I, model.T, rule=ramp_down_rule)
    model.ConBalance = Constraint(model.T, rule=Balance)
    model.Pres_max = Constraint(model.T, rule=Pres_max)

    # Add the objective functions to the model using ObjectiveList(). Note
    # that the first index is 1 instead of 0!
    model.obj_list = ObjectiveList()
    model.obj_list.add(expr=cost_objective(model), sense=minimize)
    model.obj_list.add(expr=emissions_objective(model), sense=minimize)
    model.obj_list.add(expr=unmet_objective(model), sense=minimize)

    # By default deactivate all the objective functions
    for o in range(len(model.obj_list)):
        model.obj_list[o + 1].deactivate()

    return model
Beispiel #27
0
 def test_len1(self):
     model = self.model
     model = ConcreteModel()
     model.c = self._ctype()
     self.assertEqual(len(model.c), 0)
Beispiel #28
0
 def setUp(self):
     self.model = ConcreteModel()
     self.model.x = Var()
     # set by derived class
     self._arg = None
Beispiel #29
0
    def __init__(self, nfe_t, ncp_t, **kwargs):
        ConcreteModel.__init__(self)

        steady = kwargs.pop('steady', False)
        _t = kwargs.pop('_t', 1.0)
        Ntray = kwargs.pop('Ntray', 42)
        # --------------------------------------------------------------------------------------------------------------
        # Orthogonal Collocation Parameters section

        # Radau
        self._alp_gauB_t = 1
        self._bet_gauB_t = 0

        if steady:
            print("[I] " + str(self.__class__.__name__) + " NFE and NCP Overriden - Steady state mode")
            self.nfe_t = 1
            self.ncp_t = 1
        else:
            self.nfe_t = nfe_t
            self.ncp_t = ncp_t

        self.tau_t = collptsgen(self.ncp_t, self._alp_gauB_t, self._bet_gauB_t)

        # start at zero
        self.tau_i_t = {0: 0.}
        # create a list

        for ii in range(1, self.ncp_t + 1):
            self.tau_i_t[ii] = self.tau_t[ii - 1]

        # ======= SETS ======= #
        # For finite element = 1 .. NFE
        # This has to be > 0

        self.fe_t = Set(initialize=[ii for ii in range(1, self.nfe_t + 1)])

        # collocation points
        # collocation points for differential variables
        self.cp_t = Set(initialize=[ii for ii in range(0, self.ncp_t + 1)])
        # collocation points for algebraic variables
        self.cp_ta = Set(within=self.cp_t, initialize=[ii for ii in range(1, self.ncp_t + 1)])

        # create collocation param
        self.taucp_t = Param(self.cp_t, initialize=self.tau_i_t)

        self.ldot_t = Param(self.cp_t, self.cp_t, initialize=
        (lambda m, j, k: lgrdot(k, m.taucp_t[j], self.ncp_t, self._alp_gauB_t, self._bet_gauB_t)))  #: watch out for this!

        self.l1_t = Param(self.cp_t, initialize=
        (lambda m, j: lgr(j, 1, self.ncp_t, self._alp_gauB_t, self._bet_gauB_t)))

        # --------------------------------------------------------------------------------------------------------------
        # Model parameters
        self.Ntray = Ntray
        self.tray = Set(initialize=[i for i in range(1, Ntray + 1)])
        self.feed = Param(self.tray,
                          initialize=lambda m, t: 57.5294 if t == 21 else 0.0,
                          mutable=True)

        self.xf = Param(initialize=0.32, mutable=True)  # feed mole fraction
        self.hf = Param(initialize=9081.3)  # feed enthalpy

        self.hlm0 = Param(initialize=2.6786e-04)
        self.hlma = Param(initialize=-0.14779)
        self.hlmb = Param(initialize=97.4289)
        self.hlmc = Param(initialize=-2.1045e04)

        self.hln0 = Param(initialize=4.0449e-04)
        self.hlna = Param(initialize=-0.1435)
        self.hlnb = Param(initialize=121.7981)
        self.hlnc = Param(initialize=-3.0718e04)

        self.r = Param(initialize=8.3147)
        self.a = Param(initialize=6.09648)
        self.b = Param(initialize=1.28862)
        self.c1 = Param(initialize=1.016)
        self.d = Param(initialize=15.6875)
        self.l = Param(initialize=13.4721)
        self.f = Param(initialize=2.615)

        self.gm = Param(initialize=0.557)
        self.Tkm = Param(initialize=512.6)
        self.Pkm = Param(initialize=8.096e06)

        self.gn = Param(initialize=0.612)
        self.Tkn = Param(initialize=536.7)
        self.Pkn = Param(initialize=5.166e06)

        self.CapAm = Param(initialize=23.48)
        self.CapBm = Param(initialize=3626.6)
        self.CapCm = Param(initialize=-34.29)

        self.CapAn = Param(initialize=22.437)
        self.CapBn = Param(initialize=3166.64)
        self.CapCn = Param(initialize=-80.15)

        self.pstrip = Param(initialize=250)
        self.prect = Param(initialize=190)

        def _p_init(m, t):
            ptray = 9.39e04
            if t <= 20:
                return _p_init(m, 21) + m.pstrip * (21 - t)
            elif 20 < t < m.Ntray:
                return ptray + m.prect * (m.Ntray - t)
            elif t == m.Ntray:
                return 9.39e04

        self.p = Param(self.tray, initialize=_p_init)

        self.T29_des = Param(initialize=343.15)
        self.T15_des = Param(initialize=361.15)
        self.Dset = Param(initialize=1.83728)
        self.Qcset = Param(initialize=1.618890)
        self.Qrset = Param(initialize=1.786050)
        # self.Recset = Param()

        self.alpha_T29 = Param(initialize=1)
        self.alpha_T15 = Param(initialize=1)
        self.alpha_D = Param(initialize=1)
        self.alpha_Qc = Param(initialize=1)
        self.alpha_Qr = Param(initialize=1)
        self.alpha_Rec = Param(initialize=1)

        def _alpha_init(m, i):
            if i <= 21:
                return 0.62
            else:
                return 0.35

        self.alpha = Param(self.tray,
                           initialize=lambda m, t: 0.62 if t <= 21 else 0.35)

        # --------------------------------------------------------------------------------------------------------------
        #: First define differential state variables (state: x, ic-Param: x_ic, derivative-Var:dx_dt
        #: States (differential) section
        zero_tray = dict.fromkeys(self.tray)
        zero3 = dict.fromkeys(self.fe_t * self.cp_t * self.tray)

        for key in zero3.keys():
            zero3[key] = 0.0

        def __m_init(m, i, j, t):
            if t < m.Ntray:
                return 4000.
            elif t == 1:
                return 104340.
            elif t == m.Ntray:
                return 5000.

        #: Liquid hold-up
        self.M = Var(self.fe_t, self.cp_t, self.tray,
                     initialize=__m_init)
        #: Mole-fraction
        self.x = Var(self.fe_t, self.cp_t, self.tray, initialize=lambda m, i, j, t: 0.999 * t / m.Ntray)

        #: Initial state-Param
        self.M_ic = zero_tray if steady else Param(self.tray, initialize=0.0, mutable=True)
        self.x_ic = zero_tray if steady else Param(self.tray, initialize=0.0, mutable=True)

        #:  Derivative-var
        self.dM_dt = zero3 if steady else Var(self.fe_t, self.cp_t, self.tray, initialize=0.0)
        self.dx_dt = zero3 if steady else Var(self.fe_t, self.cp_t, self.tray, initialize=0.0)

        # --------------------------------------------------------------------------------------------------------------
        # States (algebraic) section
        # Tray temperature
        self.T = Var(self.fe_t, self.cp_ta, self.tray,
                     initialize=lambda m, i, j, t: ((370.781 - 335.753) / m.Ntray) * t + 370.781)
        self.Tdot = Var(self.fe_t, self.cp_ta, self.tray, initialize=1e-05)  #: Not really a der_var

        # saturation pressures
        self.pm = Var(self.fe_t, self.cp_ta, self.tray, initialize=1e4)
        self.pn = Var(self.fe_t, self.cp_ta, self.tray, initialize=1e4)

        # Vapor mole flowrate
        self.V = Var(self.fe_t, self.cp_ta, self.tray, initialize=44.0)

        def _l_init(m, i, j, t):
            if 2 <= t <= 21:
                return 83.
            elif 22 <= t <= 42:
                return 23
            elif t == 1:
                return 40

        # Liquid mole flowrate
        self.L = Var(self.fe_t, self.cp_ta, self.tray, initialize=_l_init)

        # Vapor mole frac & diff var
        self.y = Var(self.fe_t, self.cp_ta, self.tray,
                     initialize=lambda m, i, j, t: ((0.99 - 0.005) / m.Ntray) * t + 0.005)

        # Liquid enthalpy    # enthalpy
        self.hl = Var(self.fe_t, self.cp_ta, self.tray, initialize=10000.)

        # Liquid enthalpy    # enthalpy
        self.hv = Var(self.fe_t, self.cp_ta, self.tray, initialize=5e+04)
        # Re-boiler & condenser heat
        self.Qc = Var(self.fe_t, self.cp_ta, initialize=1.6e06)
        self.D = Var(self.fe_t, self.cp_ta, initialize=18.33)
        # vol holdups
        self.Vm = Var(self.fe_t, self.cp_ta, self.tray, initialize=6e-05)

        self.Mv = Var(self.fe_t, self.cp_ta, self.tray,
                      initialize=lambda m, i, j, t: 0.23 if 1 < t < m.Ntray else 0.0)
        self.Mv1 = Var(self.fe_t, self.cp_ta, initialize=8.57)
        self.Mvn = Var(self.fe_t, self.cp_ta, initialize=0.203)

        hi_t = dict.fromkeys(self.fe_t)
        for key in hi_t.keys():
            hi_t[key] = 1.0 if steady else _t/self.nfe_t

        self.hi_t = hi_t if steady else Param(self.fe_t, initialize=hi_t)

        # --------------------------------------------------------------------------------------------------------------
        #: Controls
        self.u1 = Param(self.fe_t, initialize=7.72700925775773761472464684629813E-01, mutable=True)  #: Dummy
        self.u2 = Param(self.fe_t, initialize=1.78604740940007800236344337463379E+06, mutable=True)  #: Dummy

        self.Rec = Var(self.fe_t, initialize=7.72700925775773761472464684629813E-01)
        self.Qr = Var(self.fe_t, initialize=1.78604740940007800236344337463379E+06)

        # --------------------------------------------------------------------------------------------------------------
        #: Constraints for the differential states
        #: Then the ode-Con:de_x, collocation-Con:dvar_t_x, noisy-Expr: noisy_x, cp-Constraint: cp_x, initial-Con: x_icc
        #: Differential equations
        self.de_M = Constraint(self.fe_t, self.cp_ta, self.tray, rule=m_ode)
        self.de_x = Constraint(self.fe_t, self.cp_ta, self.tray, rule=x_ode)

        #: Collocation equations
        self.dvar_t_M = None if steady else Constraint(self.fe_t, self.cp_ta, self.tray, rule=M_COLL)
        self.dvar_t_x = None if steady else Constraint(self.fe_t, self.cp_ta, self.tray, rule=x_coll)

        #: Continuation equations (redundancy here)
        if self.nfe_t > 1:
            #: Noisy expressions
            self.noisy_M = None if steady else Expression(self.fe_t, self.tray, rule=M_CONT)
            self.noisy_x = None if steady else Expression(self.fe_t, self.tray, rule=x_cont)

            #: Continuation equations
            self.cp_M = None if steady else \
                Constraint(self.fe_t, self.tray,
                           rule=lambda m, i, t: self.noisy_M[i, t] == 0.0 if i < self.nfe_t else Constraint.Skip)
            self.cp_x = None if steady else \
                Constraint(self.fe_t, self.tray,
                           rule=lambda m, i, t: self.noisy_x[i, t] == 0.0 if i < self.nfe_t else Constraint.Skip)

        #: Initial condition-Constraints
        self.M_icc = None if steady else Constraint(self.tray, rule=acm)
        self.x_icc = None if steady else Constraint(self.tray, rule=acx)

        # --------------------------------------------------------------------------------------------------------------
        #: Constraint section (algebraic equations)

        self.hrc = Constraint(self.fe_t, self.cp_ta, rule=hrc)
        self.gh = Constraint(self.fe_t, self.cp_ta, self.tray, rule=gh)
        self.ghb = Constraint(self.fe_t, self.cp_ta, rule=ghb)
        self.ghc = Constraint(self.fe_t, self.cp_ta, rule=ghc)
        self.hkl = Constraint(self.fe_t, self.cp_ta, self.tray, rule=hkl)
        self.hkv = Constraint(self.fe_t, self.cp_ta, self.tray, rule=hkv)
        self.lpself = Constraint(self.fe_t, self.cp_ta, self.tray, rule=lpm)
        self.lpn = Constraint(self.fe_t, self.cp_ta, self.tray, rule=lpn)
        self.dp = Constraint(self.fe_t, self.cp_ta, self.tray, rule=dp)
        self.lTdot = Constraint(self.fe_t, self.cp_ta, self.tray, rule=lTdot)
        self.gy0 = Constraint(self.fe_t, self.cp_ta, rule=gy0)
        self.gy = Constraint(self.fe_t, self.cp_ta, self.tray, rule=gy)
        self.dMV = Constraint(self.fe_t, self.cp_ta, self.tray, rule=dMV)
        self.dMv1 = Constraint(self.fe_t, self.cp_ta, rule=dMv1)
        self.dMvn = Constraint(self.fe_t, self.cp_ta, rule=dMvn)
        self.hyd = Constraint(self.fe_t, self.cp_ta, self.tray, rule=hyd)
        self.hyd1 = Constraint(self.fe_t, self.cp_ta, rule=hyd1)
        self.hydN = Constraint(self.fe_t, self.cp_ta, rule=hydN)
        self.dvself = Constraint(self.fe_t, self.cp_ta, self.tray, rule=dvm)

        # --------------------------------------------------------------------------------------------------------------
        #: Control constraint
        self.u1_e = Expression(self.fe_t, rule=lambda m, i: self.Rec[i])
        self.u2_e = Expression(self.fe_t, rule=lambda m, i: self.Qr[i])

        self.u1_c = Constraint(self.fe_t, rule=lambda m, i: self.u1[i] == self.u1_e[i])
        self.u2_c = Constraint(self.fe_t, rule=lambda m, i: self.u2[i] == self.u2_e[i])
        # --------------------------------------------------------------------------------------------------------------
        #: Suffixes
        self.dual = Suffix(direction=Suffix.IMPORT_EXPORT)
        self.ipopt_zL_out = Suffix(direction=Suffix.IMPORT)
        self.ipopt_zU_out = Suffix(direction=Suffix.IMPORT)
        self.ipopt_zL_in = Suffix(direction=Suffix.EXPORT)
        self.ipopt_zU_in = Suffix(direction=Suffix.EXPORT)
Beispiel #30
0
def _rule_t0(m, n):
    return m.T[0, n] == m.T_ic[n]


def _rule_tj0(m, n):
    return m.Tj[0, n] == m.Tj_ic[n]


#: type: (int, int, dict)
"""
    CSTR from Rodrigo's thesis
Returns:
    cstr_rodrigo_dae: The model itmod. Without discretization.
"""
#: if steady == True fallback to steady-state computation
mod = ConcreteModel()
#: mod.nfe_t = nfe_t  #:
#: mod.ncp_t = ncp_t
mod.discretized = False
ncstr = 1
mod.ncstr = Set(initialize=[i for i in range(0, ncstr)])

mod.t = ContinuousSet(bounds=(0, 1))

mod.Cainb = Param(default=1.0)
mod.Tinb = Param(default=275.0)
# mod.Tjinb = Param(default=250.0)

#: Our control var
mod.Tjinb = Var(mod.t, initialize=250)
mod.u1 = Param(mod.t, default=250,
def representative(duration_repr,
                   selection,
                   VWat=75000,
                   solArea=2 * (18300 + 15000),
                   VSTC=75000,
                   pipe_model='ExtensivePipe',
                   time_step=3600):
    """

    Args:
        duration_repr:
        selection:
        VWat:
        solArea:
        VSTC:
        pipe_model:
        time_step:

    Returns:

    """
    unit_sec = 3600 * 24  # Seconds per unit time of duration (seconds per day)

    netGraph = CaseFuture.make_graph(repr=True)

    import pandas as pd
    import time

    begin = time.clock()
    topmodel = ConcreteModel()

    # In[14]:

    optimizers = {}
    epoch = pd.Timestamp('20140101')
    for start_day, duration in selection.items():
        start_time = epoch + pd.Timedelta(days=start_day)
        optmodel = Modesto(graph=netGraph, pipe_model=pipe_model)
        for comp in optmodel.get_node_components(
                filter_type='StorageCondensed').values():
            comp.set_reps(num_reps=int(duration))
        topmodel.add_component(name='repr_' + str(start_day),
                               val=optmodel.model)

        #####################
        # Assign parameters #
        #####################

        optmodel = CaseFuture.set_params(
            optmodel,
            pipe_model=pipe_model,
            repr=True,
            horizon=duration_repr * unit_sec,
            time_step=time_step,
        )
        optmodel.change_param(node='SolarArray',
                              comp='solar',
                              param='area',
                              val=solArea)
        optmodel.change_param(node='SolarArray',
                              comp='tank',
                              param='volume',
                              val=VSTC)
        optmodel.change_param(node='WaterscheiGarden',
                              comp='tank',
                              param='volume',
                              val=VWat)

        optmodel.change_param(node='Production',
                              comp='backup',
                              param='ramp',
                              val=0)
        optmodel.change_param(node='Production',
                              comp='backup',
                              param='ramp_cost',
                              val=0)

        optmodel.compile(start_time=start_time)
        # optmodel.set_objective('energy')

        optimizers[start_day] = optmodel

    # In[ ]:

    ##############################
    # Compile aggregated problem #
    ##############################

    selected_days = selection.keys()

    for i, next_day in enumerate(selected_days):
        current = selected_days[i - 1]

        next_heat = optimizers[next_day].get_node_components(
            filter_type='StorageCondensed')
        current_heat = optimizers[current].get_node_components(
            filter_type='StorageCondensed')

        for component_id in next_heat:
            # Link begin and end of representative periods
            def _link_stor(m):
                """

                Args:
                    m:

                Returns:

                """
                return next_heat[component_id].get_heat_stor_init() == \
                       current_heat[component_id].get_heat_stor_final()

            topmodel.add_component(name='_'.join(
                [component_id, str(current), 'eq']),
                                   val=Constraint(rule=_link_stor))
            # print 'State equation added for storage {} in representative week starting on day {}'.format(
            #     component_id,
            #     current)

    # In[ ]:

    def _top_objective(m):
        """

        Args:
            m:

        Returns:

        """
        return 365 / (duration_repr * (365 // duration_repr)) * sum(
            repetitions * optimizers[start_day].get_objective(objtype='energy',
                                                              get_value=False)
            for start_day, repetitions in selection.items())

    # Factor 365/364 to make up for missing day
    # set get_value to False to return object instead of value of the objective function
    topmodel.obj = Objective(rule=_top_objective, sense=minimize)

    # In[ ]:

    end = time.clock()

    # print 'Writing time:', str(end - begin)

    return topmodel, optimizers
Beispiel #32
0
    def test_indexed_by(self):
        m = ConcreteModel()
        m.time = ContinuousSet(bounds=(0, 10))
        m.space = ContinuousSet(bounds=(0, 10))
        m.set = Set(initialize=['a', 'b', 'c'])
        m.set2 = Set(initialize=[('a', 1), ('b', 2)])
        m.v = Var()
        m.v1 = Var(m.time)
        m.v2 = Var(m.time, m.space)
        m.v3 = Var(m.set, m.space, m.time)
        m.v4 = Var(m.time, m.set2)
        m.v5 = Var(m.set2, m.time, m.space)

        @m.Block()
        def b(b):
            b.v = Var()
            b.v1 = Var(m.time)
            b.v2 = Var(m.time, m.space)
            b.v3 = Var(m.set, m.space, m.time)

        @m.Block(m.time)
        def b1(b):
            b.v = Var()
            b.v1 = Var(m.space)
            b.v2 = Var(m.space, m.set)

        @m.Block(m.time, m.space)
        def b2(b):
            b.v = Var()
            b.v1 = Var(m.set)

            @b.Block()
            def b(bl):
                bl.v = Var()
                bl.v1 = Var(m.set)
                bl.v2 = Var(m.time)

        @m.Block(m.set2, m.time)
        def b3(b):
            b.v = Var()
            b.v1 = Var(m.space)

            @b.Block(m.space)
            def b(bb):
                bb.v = Var(m.set)

        disc = TransformationFactory('dae.collocation')
        disc.apply_to(m, wrt=m.time, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')
        disc.apply_to(m, wrt=m.space, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')

        self.assertFalse(is_explicitly_indexed_by(m.v, m.time))
        self.assertTrue(is_explicitly_indexed_by(m.b.v2, m.space))
        self.assertTrue(is_explicitly_indexed_by(m.b.v3, m.time, m.space))

        self.assertFalse(is_in_block_indexed_by(m.v1, m.time))
        self.assertFalse(is_in_block_indexed_by(m.v2, m.set))
        self.assertTrue(is_in_block_indexed_by(m.b1[m.time[1]].v2, m.time))

        self.assertTrue(is_in_block_indexed_by(
            m.b2[m.time[1], m.space[1]].b.v1, m.time))
        self.assertTrue(is_in_block_indexed_by(
            m.b2[m.time[1], m.space[1]].b.v2, m.time))
        self.assertTrue(is_explicitly_indexed_by(
            m.b2[m.time[1], m.space[1]].b.v2, m.time))
        self.assertFalse(is_in_block_indexed_by(
            m.b2[m.time[1], m.space[1]].b.v1, m.set))

        self.assertFalse(is_in_block_indexed_by(
            m.b2[m.time[1], m.space[1]].b.v1, 
            m.space, stop_at=m.b2[m.time[1], m.space[1]]))

        # Explicit indexing with multi-dimensional set:
        self.assertTrue(is_explicitly_indexed_by(m.v4, m.time, m.set2))
        self.assertTrue(is_explicitly_indexed_by(m.v5, m.time, m.set2, m.space))

        # Implicit indexing with multi-dimensional set:
        self.assertTrue(is_in_block_indexed_by(
            m.b3['a', 1, m.time[1]].v, m.set2))
        self.assertTrue(is_in_block_indexed_by(
            m.b3['a', 1, m.time[1]].v, m.time))
        self.assertTrue(is_in_block_indexed_by(
            m.b3['a', 1, m.time[1]].v1[m.space[1]], m.set2))
        self.assertFalse(is_in_block_indexed_by(
            m.b3['a', 1, m.time[1]].v1[m.space[1]], m.space))
        self.assertTrue(is_in_block_indexed_by(
            m.b3['b', 2, m.time[2]].b[m.space[2]].v['b'], m.set2))
        self.assertTrue(is_in_block_indexed_by(
            m.b3['b', 2, m.time[2]].b[m.space[2]].v['b'], m.time))
        self.assertTrue(is_in_block_indexed_by(
            m.b3['b', 2, m.time[2]].b[m.space[2]].v['b'], m.space))
        self.assertFalse(is_in_block_indexed_by(
            m.b3['b', 2, m.time[2]].b[m.space[2]].v['b'], m.set))
        self.assertFalse(is_in_block_indexed_by(
            m.b3['b', 2, m.time[2]].b[m.space[2]].v['b'], m.time,
            stop_at=m.b3['b', 2, m.time[2]]))
        self.assertFalse(is_in_block_indexed_by(
            m.b3['b', 2, m.time[2]].b[m.space[2]].v['b'], m.time,
            stop_at=m.b3))
Beispiel #33
0
    def test_get_index_set_except(self):
        '''
        Tests:
          For components indexed by 0, 1, 2, 3, 4 sets:
            get_index_set_except one, then two (if any) of those sets
            check two items that should be in set_except
            insert item(s) back into these sets via index_getter
        '''
        m = ConcreteModel()
        m.time = ContinuousSet(bounds=(0, 10))
        m.space = ContinuousSet(bounds=(0, 10))
        m.set1 = Set(initialize=['a', 'b', 'c'])
        m.set2 = Set(initialize=['d', 'e', 'f'])
        m.v = Var()
        m.v1 = Var(m.time)
        m.v2 = Var(m.time, m.space)
        m.v3 = Var(m.time, m.space, m.set1)
        m.v4 = Var(m.time, m.space, m.set1, m.set2)

        # Multi-dimensional set:
        m.set3 = Set(initialize=[('a', 1), ('b', 2)])
        m.v5 = Var(m.set3)
        m.v6 = Var(m.time, m.space, m.set3)
        m.v7 = Var(m.set3, m.space, m.time)

        disc = TransformationFactory('dae.collocation')
        disc.apply_to(m, wrt=m.time, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')
        disc.apply_to(m, wrt=m.space, nfe=5, ncp=2, scheme='LAGRANGE-RADAU')

        # Want this to give a TypeError
        # info = get_index_set_except(m.v, m.time)

        # Indexed by one set
        info = get_index_set_except(m.v1, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(set_except == [None])
        # Variable is not indexed by anything except time
        # Test that index_getter returns only the new value given,
        # regardless of whether it was part of the set excluded (time):
        self.assertEqual(index_getter((), -1), -1)

        # Indexed by two sets
        info = get_index_set_except(m.v2, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(m.space[1] in set_except
                        and m.space.last() in set_except)
	# Here (2,) is the partial index, corresponding to space.
        # Can be provided as a scalar or tuple. 4, the time index,
        # should be inserted before (2,)
        self.assertEqual(index_getter((2,), 4), (4, 2))
        self.assertEqual(index_getter(2, 4), (4, 2))

        # Case where every set is "omitted," now for multiple sets
        info = get_index_set_except(m.v2, m.space, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(set_except == [None])
        # 5, 7 are the desired index values for space, time 
        # index_getter should put them in the right order for m.v2,
        # even if they are not valid indices for m.v2
        self.assertEqual(index_getter((), 5, 7), (7, 5))

        # Indexed by three sets
        info = get_index_set_except(m.v3, m.time)
        # In this case set_except is a product of the two non-time sets
        # indexing v3
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue((m.space[1], 'b') in set_except
                        and (m.space.last(), 'a') in set_except)
        # index_getter inserts a scalar index into an index of length 2
        self.assertEqual(index_getter((2, 'b'), 7), (7, 2, 'b'))

        info = get_index_set_except(m.v3, m.space, m.time)
        # Two sets omitted. Now set_except is just set1
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue('a' in set_except)
        # index_getter inserts the two new indices in the right order
        self.assertEqual(index_getter('b', 1.2, 1.1), (1.1, 1.2, 'b'))

        # Indexed by four sets
        info = get_index_set_except(m.v4, m.set1, m.space)
        # set_except is a product, and there are two indices to insert
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue((m.time[1], 'd') in set_except)
        self.assertEqual(index_getter((4, 'f'), 'b', 8), (4, 8, 'b', 'f'))
        
        # The intended usage of this function looks something like:
        index_set = m.v4.index_set()
        for partial_index in set_except:
            complete_index = index_getter(partial_index, 'a', m.space[2])
            self.assertTrue(complete_index in index_set)
            # Do something for every index of v4 at 'a' and space[2]

        # Indexed by a multi-dimensional set
        info = get_index_set_except(m.v5, m.set3)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertEqual(set_except, [None])
        self.assertEqual(index_getter((), ('a', 1)), ('a', 1))

        info = get_index_set_except(m.v6, m.set3, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertTrue(m.space[1] in set_except)
        self.assertEqual(index_getter(m.space[1], ('b', 2), m.time[1]),
                (m.time[1], m.space[1], 'b', 2))

        info = get_index_set_except(m.v7, m.time)
        set_except = info['set_except']
        index_getter = info['index_getter']
        self.assertIn(('a', 1, m.space[1]), set_except)
        self.assertEqual(index_getter(('a', 1, m.space[1]), m.time[1]),
                         ('a', 1, m.space[1], m.time[1]))

        m.v8 = Var(m.time, m.set3, m.time)
        with self.assertRaises(ValueError):
            info = get_index_set_except(m.v8, m.time)
        with self.assertRaises(ValueError):
            info = get_index_set_except(m.v8, m.space)
def three_objective_model():
    model = ConcreteModel()

    # Define variables
    model.LIGN = Var(within=NonNegativeReals)
    model.LIGN1 = Var(within=NonNegativeReals)
    model.LIGN2 = Var(within=NonNegativeReals)
    model.OIL = Var(within=NonNegativeReals)
    model.OIL2 = Var(within=NonNegativeReals)
    model.OIL3 = Var(within=NonNegativeReals)
    model.NG = Var(within=NonNegativeReals)
    model.NG1 = Var(within=NonNegativeReals)
    model.NG2 = Var(within=NonNegativeReals)
    model.NG3 = Var(within=NonNegativeReals)
    model.RES = Var(within=NonNegativeReals)
    model.RES1 = Var(within=NonNegativeReals)
    model.RES3 = Var(within=NonNegativeReals)

    # --------------------------------------
    #   Define the objective functions
    # --------------------------------------

    def objective1(model):
        return 30 * model.LIGN + 75 * model.OIL + 60 * model.NG + 90 * model.RES

    def objective2(model):
        return 1.44 * model.LIGN + 0.72 * model.OIL + 0.45 * model.NG

    def objective3(model):
        return model.OIL + model.NG

    # --------------------------------------
    #   Define the regular constraints
    # --------------------------------------

    def constraint1(model):
        return model.LIGN - model.LIGN1 - model.LIGN2 == 0

    def constraint2(model):
        return model.OIL - model.OIL2 - model.OIL3 == 0

    def constraint3(model):
        return model.NG - model.NG1 - model.NG2 - model.NG3 == 0

    def constraint4(model):
        return model.RES - model.RES1 - model.RES3 == 0

    def constraint5(model):
        return model.LIGN <= 31000

    def constraint6(model):
        return model.OIL <= 15000

    def constraint7(model):
        return model.NG <= 22000

    def constraint8(model):
        return model.RES <= 10000

    def constraint9(model):
        return model.LIGN1 + model.NG1 + model.RES1 >= 38400

    def constraint10(model):
        return model.LIGN2 + model.OIL2 + model.NG2 >= 19200

    def constraint11(model):
        return model.OIL3 + model.NG3 + model.RES3 >= 6400

    # --------------------------------------
    #   Add components to the model
    # --------------------------------------

    # Add the constraints to the model
    model.con1 = Constraint(rule=constraint1)
    model.con2 = Constraint(rule=constraint2)
    model.con3 = Constraint(rule=constraint3)
    model.con4 = Constraint(rule=constraint4)
    model.con5 = Constraint(rule=constraint5)
    model.con6 = Constraint(rule=constraint6)
    model.con7 = Constraint(rule=constraint7)
    model.con8 = Constraint(rule=constraint8)
    model.con9 = Constraint(rule=constraint9)
    model.con10 = Constraint(rule=constraint10)
    model.con11 = Constraint(rule=constraint11)

    # Add the objective functions to the model using ObjectiveList(). Note
    # that the first index is 1 instead of 0!
    model.obj_list = ObjectiveList()
    model.obj_list.add(expr=objective1(model), sense=minimize)
    model.obj_list.add(expr=objective2(model), sense=minimize)
    model.obj_list.add(expr=objective3(model), sense=minimize)

    # By default deactivate all the objective functions
    for o in range(len(model.obj_list)):
        model.obj_list[o + 1].deactivate()

    return model
Beispiel #35
0
    def _dualize(self, block, unfixed=[]):
        """
        Generate the dual of a block
        """
        #
        # Collect linear terms from the block
        #
        A, b_coef, c_rhs, c_sense, d_sense, vnames, cnames, v_domain = collect_linear_terms(
            block, unfixed)
        ##print(A)
        ##print(vnames)
        ##print(cnames)
        ##print(list(A.keys()))
        ##print("---")
        ##print(A.keys())
        ##print(c_sense)
        ##print(c_rhs)
        #
        # Construct the block
        #
        if isinstance(block, Model):
            dual = ConcreteModel()
        else:
            dual = Block()
        dual.construct()
        _vars = {}

        def getvar(name, ndx=None):
            v = _vars.get((name, ndx), None)
            if v is None:
                v = Var()
                if ndx is None:
                    v_name = name
                elif type(ndx) is tuple:
                    v_name = "%s[%s]" % (name, ','.join(map(str, ndx)))
                else:
                    v_name = "%s[%s]" % (name, str(ndx))
                setattr(dual, v_name, v)
                _vars[name, ndx] = v
            return v

        #
        # Construct the objective
        #
        if d_sense == minimize:
            dual.o = Objective(expr=sum(-b_coef[name, ndx] * getvar(name, ndx)
                                        for name, ndx in b_coef),
                               sense=d_sense)
        else:
            dual.o = Objective(expr=sum(b_coef[name, ndx] * getvar(name, ndx)
                                        for name, ndx in b_coef),
                               sense=d_sense)
        #
        # Construct the constraints
        #
        for cname in A:
            for ndx, terms in iteritems(A[cname]):
                expr = 0
                for term in terms:
                    expr += term.coef * getvar(term.var, term.ndx)
                if not (cname, ndx) in c_rhs:
                    c_rhs[cname, ndx] = 0.0
                if c_sense[cname, ndx] == 'e':
                    e = expr - c_rhs[cname, ndx] == 0
                elif c_sense[cname, ndx] == 'l':
                    e = expr - c_rhs[cname, ndx] <= 0
                else:
                    e = expr - c_rhs[cname, ndx] >= 0
                c = Constraint(expr=e)
                if ndx is None:
                    c_name = cname
                elif type(ndx) is tuple:
                    c_name = "%s[%s]" % (cname, ','.join(map(str, ndx)))
                else:
                    c_name = "%s[%s]" % (cname, str(ndx))
                setattr(dual, c_name, c)
            #
            for (name, ndx), domain in iteritems(v_domain):
                v = getvar(name, ndx)
                flag = type(ndx) is tuple and (ndx[-1] == 'lb'
                                               or ndx[-1] == 'ub')
                if domain == 1:
                    v.domain = NonNegativeReals
                elif domain == -1:
                    v.domain = NonPositiveReals
                else:
                    # TODO: verify that this case is possible
                    v.domain = Reals

        return dual
 def test_len1(self):
     model = self.model
     model = ConcreteModel()
     model.c = self._ctype()
     self.assertEqual(len(model.c), 0)