Esempio n. 1
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
Esempio n. 2
0
    def convert_prob(self):
        self.logger.info("Converting optimization problem")

        self.model.con_list = ConstraintList()

        # Set of objective functions
        self.model.Os = Set(ordered=True, initialize=[o + 2 for o in self.iter_obj2])

        # Slack for objectives introduced as constraints
        self.model.Slack = Var(self.model.Os, within=NonNegativeReals)
        self.model.e = Param(
            self.model.Os,
            initialize=[np.nan for _ in self.model.Os],
            within=Any,
            mutable=True,
        )  # RHS of constraints

        # Add p-1 objective functions as constraints
        for o in range(1, self.n_obj):
            self.model.obj_list[1].expr += self.opts.eps * (
                10 ** (-1 * (o - 1)) * self.model.Slack[o + 1] / self.obj_range[o - 1]
            )

            self.model.con_list.add(
                expr=self.model.obj_list[o + 1].expr - self.model.Slack[o + 1]
                == self.model.e[o + 1]
            )
Esempio n. 3
0
 def __init__(self, pyomo_model):
     """Constructor"""
     args = (Set(),)
     kwargs = {}
     self.pyomo_model = pyomo_model
     Objective.__init__(self, *args, **kwargs)
     #self._data = ObjectiveDataSequence( poek_model )
     self._data = []
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
Esempio n. 5
0
    def set_external_model(self, external_grey_box_model):
        self._ex_model = ex_model = external_grey_box_model
        if ex_model is None:
            self._input_names = self._output_names = None
            self.inputs = self.outputs = None
            return

        self._input_names = ex_model.input_names()
        if self._input_names is None or len(self._input_names) == 0:
            raise ValueError(
                'No input_names specified for external_grey_box_model.'
                ' Must specify at least one input.')
        self._input_names_set = Set(initialize=self._input_names, ordered=True)
        self.inputs = Var(self._input_names_set)

        self._equality_constraint_names = ex_model.equality_constraint_names()
        self._output_names = ex_model.output_names()

        self._output_names_set = Set(initialize=self._output_names, ordered=True)
        self.outputs = Var(self._output_names_set)

        # call the callback so the model can set initialization, bounds, etc.
        external_grey_box_model.finalize_block_construction(self)
Esempio n. 6
0
    def make_noisy(self, cov_dict, conf_level=2):
        self.d1.name = "Noisy plant (d1)"
        k = 0
        for x in self.states:
            s = getattr(self.d1, x)  #: state
            xicc = getattr(self.d1, x + "_icc")
            xicc.deactivate()
            for j in self.state_vars[x]:
                self.xp_l.append(s[(1, 0) + j])
                self.xp_key[(x, j)] = k
                k += 1

        self.d1.xS_pnoisy = Set(initialize=[
            i for i in range(0, len(self.xp_l))
        ])  #: Create set of noisy_states
        self.d1.w_pnoisy = Var(self.d1.xS_pnoisy,
                               initialize=0.0)  #: Model disturbance
        self.d1.Q_pnoisy = Param(self.d1.xS_pnoisy, initialize=1, mutable=True)
        self.d1.obj_fun_noisy = Objective(
            sense=maximize,
            expr=0.5 * sum(self.d1.Q_pnoisy[k] * self.d1.w_pnoisy[k]**2
                           for k in self.d1.xS_pnoisy))
        self.d1.ics_noisy = ConstraintList()

        k = 0
        for x in self.states:
            s = getattr(self.d1, x)  #: state
            xic = getattr(self.d1, x + "_ic")
            for j in self.state_vars[x]:
                expr = s[(1, 1) + j] == xic[j] + self.d1.w_pnoisy[k]
                self.d1.ics_noisy.add(expr)
                k += 1

        for key in cov_dict:
            vni = key
            v_i = self.xp_key[vni]
            self.d1.Q_pnoisy[v_i].value = cov_dict[vni]
            self.d1.w_pnoisy[v_i].setlb(-conf_level * cov_dict[vni])
            self.d1.w_pnoisy[v_i].setub(conf_level * cov_dict[vni])

        with open("debug.txt", "w") as f:
            self.d1.Q_pnoisy.display(ostream=f)
            self.d1.obj_fun_noisy.pprint(ostream=f)
            self.d1.ics_noisy.pprint(ostream=f)
            self.d1.w_pnoisy.display(ostream=f)
Esempio n. 7
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 create_model(self):
        """
        Create and return the mathematical model.
        """

        if options.DEBUG:
            logging.info("Creating model for day %d" % self.day_id)

        # Obtain the orders book
        book = self.orders
        complexOrders = self.complexOrders

        # Create the optimization model
        model = ConcreteModel()
        model.periods = Set(initialize=book.periods)
        maxPeriod = max(book.periods)
        model.bids = Set(initialize=range(len(book.bids)))
        model.L = Set(initialize=book.locations)
        model.sBids = Set(initialize=[
            i for i in range(len(book.bids)) if book.bids[i].type == 'SB'
        ])
        model.bBids = Set(initialize=[
            i for i in range(len(book.bids)) if book.bids[i].type == 'BB'
        ])
        model.cBids = RangeSet(len(complexOrders))  # Complex orders
        model.C = RangeSet(len(self.connections))
        model.directions = RangeSet(2)  # 1 == up, 2 = down TODO: clean

        # Variables
        model.xs = Var(model.sBids, domain=Reals,
                       bounds=(0.0, 1.0))  # Single period bids acceptance
        model.xb = Var(model.bBids, domain=Binary)  # Block bids acceptance
        model.xc = Var(model.cBids, domain=Binary)  # Complex orders acceptance
        model.pi = Var(model.L * model.periods,
                       domain=Reals,
                       bounds=self.priceCap)  # Market prices
        model.s = Var(model.bids, domain=NonNegativeReals)  # Bids
        model.sc = Var(model.cBids, domain=NonNegativeReals)  # complex orders
        model.complexVolume = Var(model.cBids, model.periods,
                                  domain=Reals)  # Bids
        model.pi_lg_up = Var(model.cBids * model.periods,
                             domain=NonNegativeReals)  # Market prices
        model.pi_lg_down = Var(model.cBids * model.periods,
                               domain=NonNegativeReals)  # Market prices
        model.pi_lg = Var(model.cBids * model.periods,
                          domain=Reals)  # Market prices

        def flowBounds(m, c, d, t):
            capacity = self.connections[c - 1].capacity_up[t] if d == 1 else \
                self.connections[c - 1].capacity_down[t]
            return (0, capacity)

        model.f = Var(model.C * model.directions * model.periods,
                      domain=NonNegativeReals,
                      bounds=flowBounds)
        model.u = Var(model.C * model.directions * model.periods,
                      domain=NonNegativeReals)

        # Objective
        def primalObj(m):
            # Single period bids cost
            expr = summation(
                {i: book.bids[i].price * book.bids[i].volume
                 for i in m.sBids}, m.xs)
            # Block bids cost
            expr += summation(
                {
                    i: book.bids[i].price * sum(book.bids[i].volumes.values())
                    for i in m.bBids
                }, m.xb)
            return -expr

        if options.PRIMAL and not options.DUAL:
            model.obj = Objective(rule=primalObj, sense=maximize)

        def primalDualObj(m):
            return primalObj(m) + sum(1e-5 * m.xc[i] for i in model.cBids)

        if options.PRIMAL and options.DUAL:
            model.obj = Objective(rule=primalDualObj, sense=maximize)

        # Complex order constraint
        if options.PRIMAL and options.DUAL:
            model.deactivate_suborders = ConstraintList()
            for o in model.cBids:
                sub_ids = complexOrders[o - 1].ids
                curves = complexOrders[o - 1].curves
                for id in sub_ids:
                    bid = book.bids[id]
                    if bid.period <= complexOrders[o - 1].SSperiods and bid.price == \
                            curves[bid.period].bids[0].price:
                        pass  # This bid, first step of the cruve in the scheduled stop periods, is not automatically deactivated when MIC constraint is not satisfied
                    else:
                        model.deactivate_suborders.add(
                            model.xs[id] <= model.xc[o])

        # Ramping constraints for complex orders
        def complex_volume_def_rule(m, o, p):
            sub_ids = complexOrders[o - 1].ids
            return m.complexVolume[o, p] == sum(m.xs[i] * book.bids[i].volume
                                                for i in sub_ids
                                                if book.bids[i].period == p)

        if options.PRIMAL:
            model.complex_volume_def = Constraint(model.cBids,
                                                  model.periods,
                                                  rule=complex_volume_def_rule)

        def complex_lg_down_rule(m, o, p):
            if p + 1 > maxPeriod or complexOrders[o - 1].ramp_down == None:
                return Constraint.Skip
            else:
                return m.complexVolume[o, p] - m.complexVolume[o, p + 1] <= complexOrders[
                                                                                o - 1].ramp_down * \
                                                                            m.xc[o]

        if options.PRIMAL and options.APPLY_LOAD_GRADIENT:
            model.complex_lg_down = Constraint(model.cBids,
                                               model.periods,
                                               rule=complex_lg_down_rule)

        def complex_lg_up_rule(m, o, p):
            if p + 1 > maxPeriod or complexOrders[o - 1].ramp_up == None:
                return Constraint.Skip
            else:
                return m.complexVolume[o, p + 1] - m.complexVolume[
                    o, p] <= complexOrders[o - 1].ramp_up

        if options.PRIMAL and options.APPLY_LOAD_GRADIENT:
            model.complex_lg_up = Constraint(
                model.cBids, model.periods,
                rule=complex_lg_up_rule)  # Balance constraint

        # Energy balance constraints
        balanceExpr = {l: {t: 0.0 for t in model.periods} for l in model.L}
        for i in model.sBids:  # Simple bids
            bid = book.bids[i]
            balanceExpr[bid.location][bid.period] += bid.volume * model.xs[i]
        for i in model.bBids:  # Block bids
            bid = book.bids[i]
            for t, v in bid.volumes.items():
                balanceExpr[bid.location][t] += v * model.xb[i]

        def balanceCstr(m, l, t):
            export = 0.0
            for c in model.C:
                if self.connections[c - 1].from_id == l:
                    export += m.f[c, 1, t] - m.f[c, 2, t]
                elif self.connections[c - 1].to_id == l:
                    export += m.f[c, 2, t] - m.f[c, 1, t]
            return balanceExpr[l][t] == export

        if options.PRIMAL:
            model.balance = Constraint(model.L * book.periods,
                                       rule=balanceCstr)

        # Surplus of single period bids
        def sBidSurplus(m, i):  # For the "usual" step orders
            bid = book.bids[i]
            if i in self.plain_single_orders:
                return m.s[i] >= (m.pi[bid.location, bid.period] -
                                  bid.price) * bid.volume
            else:
                return Constraint.Skip

        if options.DUAL:
            model.sBidSurplus = Constraint(model.sBids, rule=sBidSurplus)

        # Surplus definition for complex suborders accounting for impact of load gradient condition
        if options.DUAL:
            model.complex_sBidSurplus = ConstraintList()
            for o in model.cBids:
                sub_ids = complexOrders[o - 1].ids
                l = complexOrders[o - 1].location
                for i in sub_ids:
                    bid = book.bids[i]
                    model.complex_sBidSurplus.add(
                        model.s[i] >=
                        (model.pi[l, bid.period] + model.pi_lg[o, bid.period] -
                         bid.price) * bid.volume)

        def LG_price_def_rule(m, o, p):
            l = complexOrders[o - 1].location

            exp = 0
            if options.APPLY_LOAD_GRADIENT:
                D = complexOrders[o - 1].ramp_down
                U = complexOrders[o - 1].ramp_up
                if D is not None:
                    exp += (m.pi_lg_down[o, p - 1] if p > 1 else
                            0) - (m.pi_lg_down[o, p] if p < maxPeriod else 0)
                if U is not None:
                    exp -= (m.pi_lg_up[o, p - 1] if p > 1 else
                            0) - (m.pi_lg_up[o, p] if p < maxPeriod else 0)

            return m.pi_lg[o, p] == exp

        if options.DUAL:
            model.LG_price_def = Constraint(model.cBids,
                                            model.periods,
                                            rule=LG_price_def_rule)

        # Surplus of block bids
        def bBidSurplus(m, i):
            bid = book.bids[i]
            bidVolume = -sum(bid.volumes.values())
            bigM = (self.priceCap[1] -
                    self.priceCap[0]) * bidVolume  # FIXME tighten BIGM
            return m.s[i] + sum([
                m.pi[bid.location, t] * -v for t, v in bid.volumes.items()
            ]) >= bid.cost * bidVolume + bigM * (1 - m.xb[i])

        if options.DUAL:
            model.bBidSurplus = Constraint(model.bBids, rule=bBidSurplus)

        # Surplus of complex orders
        def cBidSurplus(m, o):
            complexOrder = complexOrders[o - 1]
            sub_ids = complexOrder.ids
            if book.bids[sub_ids[0]].volume > 0:  # supply
                bigM = sum((self.priceCap[1] - book.bids[i].price) *
                           book.bids[i].volume for i in sub_ids)
            else:
                bigM = sum((book.bids[i].price - self.priceCap[0]) *
                           book.bids[i].volume for i in sub_ids)
            return m.sc[o] + bigM * (1 - m.xc[o]) >= sum(m.s[i]
                                                         for i in sub_ids)

        if options.DUAL:
            model.cBidSurplus = Constraint(model.cBids, rule=cBidSurplus)

        # Surplus of complex orders
        def cBidSurplus_2(m, o):
            complexOrder = complexOrders[o - 1]
            expr = 0
            for i in complexOrder.ids:
                bid = book.bids[i]
                if (bid.period <= complexOrder.SSperiods) and (
                        bid.price
                        == complexOrder.curves[bid.period].bids[0].price):
                    expr += m.s[i]
            return m.sc[o] >= expr

        if options.DUAL:
            model.cBidSurplus_2 = Constraint(
                model.cBids, rule=cBidSurplus_2)  # MIC constraint

        def cMIC(m, o):
            complexOrder = complexOrders[o - 1]

            if complexOrder.FT == 0 and complexOrder.VT == 0:
                return Constraint.Skip

            expr = 0
            bigM = complexOrder.FT
            for i in complexOrder.ids:
                bid = book.bids[i]
                if (bid.period <= complexOrder.SSperiods) and (
                        bid.price
                        == complexOrder.curves[bid.period].bids[0].price):
                    bigM += (bid.volume * (self.priceCap[1] - bid.price)
                             )  # FIXME assumes order is supply
                expr += bid.volume * m.xs[i] * (bid.price - complexOrder.VT)

            return m.sc[o] + expr + bigM * (1 - m.xc[o]) >= complexOrder.FT

        if options.DUAL and options.PRIMAL:
            model.cMIC = Constraint(model.cBids, rule=cMIC)

        # Dual connections capacity
        def dualCapacity(m, c, t):
            exportPrices = 0.0
            for l in m.L:
                if l == self.connections[c - 1].from_id:
                    exportPrices += m.pi[l, t]
                elif l == self.connections[c - 1].to_id:
                    exportPrices -= m.pi[l, t]
            return m.u[c, 1, t] - m.u[c, 2, t] + exportPrices == 0.0

        if options.DUAL:
            model.dualCapacity = Constraint(model.C * model.periods,
                                            rule=dualCapacity)

        # Dual optimality
        def dualObj(m):
            dualObj = summation(m.s) + summation(m.sc)

            for o in m.cBids:
                sub_ids = complexOrders[o - 1].ids
                for id in sub_ids:
                    dualObj -= m.s[
                        id]  # Remove contribution of complex suborders which were accounted for in prevous summation over single bids

                if options.APPLY_LOAD_GRADIENT:
                    ramp_down = complexOrders[o - 1].ramp_down
                    ramp_up = complexOrders[o - 1].ramp_up
                    for p in m.periods:
                        if p == maxPeriod:
                            continue
                        if ramp_down is not None:
                            dualObj += ramp_down * m.pi_lg_down[
                                o, p]  # Add contribution of load gradient
                        if ramp_up is not None:
                            dualObj += ramp_up * m.pi_lg_up[
                                o, p]  # Add contribution of load gradient

            for c in model.C:
                for t in m.periods:
                    dualObj += self.connections[c - 1].capacity_up[t] * m.u[c,
                                                                            1,
                                                                            t]
                    dualObj += self.connections[c -
                                                1].capacity_down[t] * m.u[c, 2,
                                                                          t]

            return dualObj

        if not options.PRIMAL:
            model.obj = Objective(rule=dualObj, sense=minimize)

        def primalEqualsDual(m):
            return primalObj(m) >= dualObj(m)

        if options.DUAL and options.PRIMAL:
            model.primalEqualsDual = Constraint(rule=primalEqualsDual)

        self.model = model
Esempio n. 9
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)
Esempio n. 10
0
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
Esempio n. 11
0
    def create_nmpc(self, **kwargs):
        kwargs.pop("newnfe", self.nfe_tnmpc)
        kwargs.pop("newncp", self.ncp_tnmpc)
        self.journalist('W', self._iteration_count, "Initializing NMPC",
                        "With {:d} fe and {:d} cp".format(self.nfe_tnmpc, self.ncp_tnmpc))
        _tnmpc = self.hi_t * self.nfe_tnmpc
        self.olnmpc = self.d_mod(self.nfe_tnmpc, self.ncp_tnmpc, _t=_tnmpc)
        self.olnmpc.name = "olnmpc (Open-Loop NMPC)"
        self.olnmpc.create_bounds()

        for u in self.u:
            cv = getattr(self.olnmpc, u)  #: Get the param
            c_val = [value(cv[i]) for i in cv.keys()]  #: Current value
            self.olnmpc.del_component(cv)  #: Delete the param
            self.olnmpc.add_component(u, Var(self.olnmpc.fe_t, initialize=lambda m, i: c_val[i-1]))
            self.olnmpc.equalize_u(direction="r_to_u")
            cc = getattr(self.olnmpc, u + "_c")  #: Get the constraint
            ce = getattr(self.olnmpc, u + "_e")  #: Get the expression
            cv = getattr(self.olnmpc, u)  #: Get the new variable
            for k in cv.keys():
                cv[k].setlb(self.u_bounds[u][0])
                cv[k].setub(self.u_bounds[u][1])
            cc.clear()
            cc.rule = lambda m, i: cv[i] == ce[i]
            cc.reconstruct()
        #: Dictionary of the states for a particular time point i
        self.xmpc_l = {}
        #: Dictionary of the position for a state in the dictionary
        self.xmpc_key = {}
        #:
        self.xmpc_l[0] = []
        #: First build the name dictionary
        k = 0
        for x in self.states:
            n_s = getattr(self.olnmpc, x)  #: State
            for j in self.state_vars[x]:
                self.xmpc_l[0].append(n_s[(0, self.ncp_tnmpc) + j])
                self.xmpc_key[(x, j)] = k
                k += 1
        #: Iterate over the rest
        for t in range(1, self.nfe_tnmpc):
            self.xmpc_l[t] = []
            for x in self.states:
                n_s = getattr(self.olnmpc, x)  #: State
                for j in self.state_vars[x]:
                    self.xmpc_l[t].append(n_s[(t, self.ncp_tnmpc) + j])
        #: A set with the length of flattened states
        self.olnmpc.xmpcS_nmpc = Set(initialize=[i for i in range(0, len(self.xmpc_l[0]))])
        #: Create set of noisy_states
        self.olnmpc.xmpc_ref_nmpc = Param(self.olnmpc.xmpcS_nmpc, initialize=0.0, mutable=True)  #: Ref-state
        self.olnmpc.Q_nmpc = Param(self.olnmpc.xmpcS_nmpc, initialize=1, mutable=True)  #: Control-weight
        # (diagonal Matrices)

        self.olnmpc.Q_w_nmpc = Param(self.olnmpc.fe_t, initialize=1e-04, mutable=True)
        self.olnmpc.R_w_nmpc = Param(self.olnmpc.fe_t, initialize=1e+02, mutable=True)
        #: Build the xT*Q*x part
        self.olnmpc.xQ_expr_nmpc = Expression(expr=sum(
            sum(self.olnmpc.Q_w_nmpc[fe] *
                self.olnmpc.Q_nmpc[k] * (self.xmpc_l[fe][k] - self.olnmpc.xmpc_ref_nmpc[k])**2
                for k in self.olnmpc.xmpcS_nmpc)
                for fe in range(0, self.nfe_tnmpc)))

        #: Build the control list
        self.umpc_l = {}
        for t in range(0, self.nfe_tnmpc):
            self.umpc_l[t] = []
            for u in self.u:
                uvar = getattr(self.olnmpc, u)
                self.umpc_l[t].append(uvar[t])
        #: Create set of u
        self.olnmpc.umpcS_nmpc = Set(initialize=[i for i in range(0, len(self.umpc_l[0]))])
        #: ref u
        self.olnmpc.umpc_ref_nmpc = Param(self.olnmpc.umpcS_nmpc, initialize=0.0, mutable=True)
        self.olnmpc.R_nmpc = Param(self.olnmpc.umpcS_nmpc, initialize=1, mutable=True)  #: Control-weight
        #: Build the uT * R * u expression
        self.olnmpc.xR_expr_nmpc = Expression(expr=sum(
            sum(self.olnmpc.R_w_nmpc[fe] *
                self.olnmpc.R_nmpc[k] * (self.umpc_l[fe][k] - self.olnmpc.umpc_ref_nmpc[k]) ** 2 for k in
                self.olnmpc.umpcS_nmpc)
            for fe in range(0, self.nfe_tnmpc)))
        self.olnmpc.objfun_nmpc = Objective(expr=self.olnmpc.xQ_expr_nmpc + self.olnmpc.xR_expr_nmpc)
Esempio n. 12
0
# 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)
mod.hlmc = Param(initialize=-2.1045e04)

mod.hln0 = Param(initialize=4.0449e-04)
mod.hlna = Param(initialize=-0.1435)
mod.hlnb = Param(initialize=121.7981)
Esempio n. 13
0
    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,
               mutable=True)  #: We are making a sort-of port


def u1_rule(m, i):
    return m.Tjinb[i] == m.u1[i]
Esempio n. 14
0
from pyomo.core.base import AbstractModel, Set, PositiveIntegers, Param, Var, Constraint, Objective, \
    ConcreteModel, NonNegativeReals, value, maximize

model = AbstractModel()

# Nodes in the network
model.N = Set()
# Network arcs
model.A = Set(within=model.N*model.N)

# Source node
model.s = Param(within=model.N)
# Sink node
model.t = Param(within=model.N)
# Flow capacity limits
model.c = Param(model.A)

# The flow over each arc
model.f = Var(model.A, within=NonNegativeReals)

# Maximize the flow into the sink nodes
def total_rule(model):
    return sum(model.f[i,j] for (i, j) in model.A if j == value(model.t))
model.total = Objective(rule=total_rule, sense=maximize)

# Enforce an upper limit on the flow across each arc
def limit_rule(model, i, j):
    return model.f[i,j] <= model.c[i, j]
model.limit = Constraint(model.A, rule=limit_rule)

# Enforce flow through each node
Esempio n. 15
0
    def __init__(self, nfe_t, ncp_t, **kwargs):
        #: type: (int, int, dict)
        #: if steady == True fallback to steady-state computation
        self.nfe_t = nfe_t  #:
        self.ncp_t = ncp_t
        self.scheme = kwargs.pop('scheme', 'LAGRANGE-RADAU')
        self.steady = kwargs.pop('steady', False)
        self._t = kwargs.pop('_t', 1.0)
        ncstr = kwargs.pop('n_cstr', 1)
        ConcreteModel.__init__(self)
        self.ncstr = Set(initialize=[i for i in range(0, ncstr)])

        if self.steady:
            self.t = Set(initialize=[1])
        else:
            self.t = ContinuousSet(bounds=(0, self._t))

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

        self.V = Param(initialize=100)
        self.UA = Param(initialize=20000 * 60)
        self.rho = Param(initialize=1000)
        self.Cp = Param(initialize=4.2)
        self.Vw = Param(initialize=10)
        self.rhow = Param(initialize=1000)
        self.Cpw = Param(initialize=4.2)
        self.k0 = Param(initialize=4.11e13)
        self.E = Param(initialize=76534.704)
        self.R = Param(initialize=8.314472)
        self.Er = Param(initialize=lambda m: (value(self.E) / value(self.R)))
        self.dH = Param(initialize=596619.)

        self.F = Param(self.t, mutable=True, default=1.2000000000000000E+02)
        self.Fw = Param(self.t, mutable=True, default=3.0000000000000000E+01)

        # States
        self.Ca = Var(self.t, self.ncstr, initialize=1.60659680385930765667001907104350E-02)
        self.T = Var(self.t, self.ncstr, initialize=3.92336059452774350120307644829154E+02)
        self.Tj = Var(self.t, self.ncstr, initialize=3.77995395658401662331016268581152E+02)

        self.k = Var(self.t, self.ncstr, initialize=4.70706140E+02)
        self.kdef = Constraint(self.t, self.ncstr)

        #: These guys have to be zero at the steady-state (steady).
        zero0 = dict.fromkeys(self.t * self.ncstr)
        for key in zero0.keys():
            zero0[key] = 0.0
        if self.steady:
            self.Cadot = zero0
            self.Tdot = zero0
            self.Tjdot = zero0
        else:
            self.Cadot = DerivativeVar(self.Ca, initialize=-3.58709135E+01)
            self.Tdot = DerivativeVar(self.T, initialize=5.19191848E+03)
            self.Tjdot = DerivativeVar(self.Tj, initialize=-9.70467399E+02)
        #: These guys as well (steady).
        self.Ca_ic = Param(self.ncstr, default=1.9193793974995963E-02)
        self.T_ic = Param(self.ncstr, default=3.8400724261199036E+02)
        self.Tj_ic = Param(self.ncstr, default=3.7127352272578315E+02)

        # m.Ca_ic = Param(m.ncstr, default=1.9193793974995963E-02)
        # m.T_ic = Param(m.ncstr, default=3.8400724261199036E+02)
        # m.Tj_ic = Param(m.ncstr, default=3.7127352272578315E+02)

        self.ODE_ca = Constraint(self.t, self.ncstr)
        self.ODE_T = Constraint(self.t, self.ncstr)
        self.ODE_Tj = Constraint(self.t, self.ncstr)

        #: No need of these guys at steady.
        if self.steady:
            self.Ca_icc = None
            self.T_icc = None
            self.Tj_icc = None
        else:
            self.Ca_icc = Constraint(self.ncstr)
            self.T_icc = Constraint(self.ncstr)
            self.Tj_icc = Constraint(self.ncstr)

        def _rule_k(m, i, n):
            if i == 0:
                return Constraint.Skip
            else:
                return m.k[i, n] == m.k0 * exp(-m.Er / m.T[i, n])

        def _rule_ca(m, i, n):
            if i == 0:
                return Constraint.Skip
            else:
                rule = m.Cadot[i, n] == (m.F[i] / m.V) * (m.Cainb - m.Ca[i, n]) - 2 * m.k[i, n] * m.Ca[i, n] ** 2
                return rule

        def _rule_t(m, i, n):
            if i == 0:
                return Constraint.Skip
            else:
                return m.Tdot[i, n] == (m.F[i] / m.V) * (m.Tinb - m.T[i, n]) + \
                2.0 * m.dH / (m.rho * m.Cp) * m.k[i, n] * m.Ca[i, n] ** 2 -\
                m.UA / (m.V * m.rho * m.Cp) * (m.T[i, n] - m.Tj[i, n])

        def _rule_tj(m, i, n):
            if i == 0:
                return Constraint.Skip
            else:
                return m.Tjdot[i, n] == \
                       (m.Fw[i] / m.Vw) * (m.Tjinb - m.Tj[i, n]) + m.UA / (m.Vw * m.rhow * m.Cpw) * (m.T[i, n] - m.Tj[i, n])

        def _rule_ca0(m, n):
            return m.Ca[0, n] == m.Ca_ic[n]

        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]

        # let Ca0 := 1.9193793974995963E-02 ;
        # let T0  := 3.8400724261199036E+02 ;
        # let Tj0 := 3.7127352272578315E+02 ;

        self.kdef.rule = lambda m, i, n: _rule_k(m, i, n)
        self.ODE_ca.rule = lambda m, i, n: _rule_ca(m, i, n)
        self.ODE_T.rule = lambda m, i, n: _rule_t(m, i, n)
        self.ODE_Tj.rule = lambda m, i, n: _rule_tj(m, i, n)

        if self.steady:
            pass
        else:
            self.Ca_icc.rule = lambda m, n: _rule_ca0(m, n)
            self.T_icc.rule = lambda m, n: _rule_t0(m, n)
            self.Tj_icc.rule = lambda m, n: _rule_tj0(m, n)
            self.Ca_icc.reconstruct()
            self.T_icc.reconstruct()
            self.Tj_icc.reconstruct()

        self.kdef.reconstruct()
        self.ODE_ca.reconstruct()
        self.ODE_T.reconstruct()
        self.ODE_Tj.reconstruct()


        # Declare at framework level
        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)

        self.discretizer = TransformationFactory('dae.collocation')
Esempio n. 16
0
def dist_col_Rodrigo_ss(init0, bnd_set):
    # collocation polynomial parameters

    # polynomial roots (Radau)

    m = ConcreteModel()
    m.i_flag = init0
    # set of finite elements and collocation points
    m.fe = Set(initialize=[1])
    m.cp = Set(initialize=[1])

    m.bnd_set = bnd_set

    if bnd_set:
        print("Bounds_set")

    Ntray = 42

    m.Ntray = Ntray

    m.tray = Set(initialize=[i for i in range(1, Ntray + 1)])

    def __init_feed(m, t):
        if t == 21:
            return 57.5294
        else:
            return 0

    m.feed = Param(m.tray, initialize=__init_feed)
    m.xf = Param(initialize=0.32)  # feed mole fraction
    m.hf = Param(initialize=9081.3)  # feed enthalpy

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

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

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

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

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

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

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

    m.pstrip = Param(initialize=250)
    m.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

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

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

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

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

    m.alpha = Param(m.tray, initialize=_alpha_init)

    ME0 = {}
    ME0[1] = 123790.826443232
    ME0[2] = 3898.34923206106
    ME0[3] = 3932.11766868415
    ME0[4] = 3950.13107445914
    ME0[5] = 3960.01212104318
    ME0[6] = 3965.37146944881
    ME0[7] = 3968.25340380767
    ME0[8] = 3969.78910997468
    ME0[9] = 3970.5965548502
    ME0[10] = 3971.0110096803
    ME0[11] = 3971.21368740283
    ME0[12] = 3971.30232788932
    ME0[13] = 3971.32958547037
    ME0[14] = 3971.32380573089
    ME0[15] = 3971.30024105555
    ME0[16] = 3971.26709591428
    ME0[17] = 3971.22878249852
    ME0[18] = 3971.187673073
    ME0[19] = 3971.14504284211
    ME0[20] = 3971.10157713182
    ME0[21] = 3971.05764415189
    ME0[22] = 3611.00216267141
    ME0[23] = 3766.84741932423
    ME0[24] = 3896.87907072814
    ME0[25] = 4004.98630195624
    ME0[26] = 4092.49383654928
    ME0[27] = 4161.86560059956
    ME0[28] = 4215.98509169956
    ME0[29] = 4257.69470716792
    ME0[30] = 4289.54901779038
    ME0[31] = 4313.71557755738
    ME0[32] = 4331.9642075775
    ME0[33] = 4345.70190802884
    ME0[34] = 4356.02621744716
    ME0[35] = 4363.78165047072
    ME0[36] = 4369.61159802674
    ME0[37] = 4374.00266939603
    ME0[38] = 4377.32093116489
    ME0[39] = 4379.84068162411
    ME0[40] = 4381.76685527968
    ME0[41] = 4383.25223100374
    ME0[42] = 4736.04924276762

    m.M_pred = Param(m.tray, initialize=ME0)

    XE0 = {}
    XE0[1] = 0.306547877605746
    XE0[2] = 0.398184778678485
    XE0[3] = 0.416675004386508
    XE0[4] = 0.42676332128531
    XE0[5] = 0.432244548463899
    XE0[6] = 0.435193762178033
    XE0[7] = 0.436764699693985
    XE0[8] = 0.437589297877498
    XE0[9] = 0.438010896454752
    XE0[10] = 0.43821522113022
    XE0[11] = 0.438302495819782
    XE0[12] = 0.438326730875504
    XE0[13] = 0.438317008813347
    XE0[14] = 0.438288981487008
    XE0[15] = 0.438251069561153
    XE0[16] = 0.438207802087721
    XE0[17] = 0.438161614415035
    XE0[18] = 0.438113815737636
    XE0[19] = 0.438065109638753
    XE0[20] = 0.438015874079915
    XE0[21] = 0.437966311972983
    XE0[22] = 0.724835538043496
    XE0[23] = 0.788208485334881
    XE0[24] = 0.838605564838572
    XE0[25] = 0.87793558673077
    XE0[26] = 0.908189470853012
    XE0[27] = 0.931224584141055
    XE0[28] = 0.948635083197147
    XE0[29] = 0.961724712952285
    XE0[30] = 0.971527857048483
    XE0[31] = 0.978848914860811
    XE0[32] = 0.984304939392599
    XE0[33] = 0.98836476845163
    XE0[34] = 0.991382214572503
    XE0[35] = 0.993622983870866
    XE0[36] = 0.995285909293636
    XE0[37] = 0.996519395295701
    XE0[38] = 0.997433995899531
    XE0[39] = 0.998111951760656
    XE0[40] = 0.998614376770054
    XE0[41] = 0.998986649363
    XE0[42] = 0.999262443919619

    m.x_pred = Param(m.tray, initialize=XE0)

    # hold in each tray

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

    m.M = Var(m.fe, m.cp, m.tray, initialize=__m_init)

    # m.M_0 = Var(m.fe, m.tray, initialize=1e07)

    # temperatures

    def __t_init(m, i, j, t):
        if m.i_flag:
            return ((370.781 - 335.753) / m.Ntray) * t + 370.781
        else:
            return 10.

    m.T = Var(m.fe, m.cp, m.tray, initialize=__t_init)

    # saturation pressures
    m.pm = Var(m.fe, m.cp, m.tray, initialize=1e4)
    m.pn = Var(m.fe, m.cp, m.tray, initialize=1e4)

    # define l-v flowrate

    def _v_init(m, i, j, t):
        if m.i_flag:
            return 44.
        else:
            return 0.

    m.V = Var(m.fe, m.cp, m.tray, initialize=_v_init)

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

    m.L = Var(m.fe, m.cp, m.tray, initialize=_l_init)

    # mol frac l-v

    def __x_init(m, i, j, t):
        if m.i_flag:
            return (0.999 / m.Ntray) * t
        else:
            return 1

    m.x = Var(m.fe, m.cp, m.tray, initialize=__x_init)

    #m.x_0 = Var(m.fe, m.tray)

    # av

    def __y_init(m, i, j, t):
        if m.i_flag:
            return ((0.99 - 0.005) / m.Ntray) * t + 0.005
        else:
            return 1

    m.y = Var(m.fe, m.cp, m.tray, initialize=__y_init)
    # enthalpy
    m.hl = Var(m.fe, m.cp, m.tray, initialize=10000.)

    def __hv_init(m, i, j, t):
        if m.i_flag:
            if t < m.Ntray:
                return 5e4
        else:
            return 0.0

    m.hv = Var(m.fe, m.cp, m.tray, initialize=__hv_init)
    # reboiler & condenser heat
    m.Qc = Var(m.fe, m.cp, initialize=1.6e06)
    m.D = Var(m.fe, m.cp, initialize=18.33)
    # vol holdups
    m.Vm = Var(m.fe, m.cp, m.tray, initialize=6e-05)

    def __mv_init(m, i, j, t):
        if m.i_flag:
            if 1 < t < m.Ntray:
                return 0.23
        else:
            return 0.0

    m.Mv = Var(m.fe, m.cp, m.tray, initialize=__mv_init)

    m.Mv1 = Var(m.fe, m.cp, initialize=8.57)
    m.Mvn = Var(m.fe, m.cp, initialize=0.203)

    def _bound_set(m):
        if m.bnd_set:
            for key, value in m.M.iteritems():
                value.setlb(1.0)
                value.setub(1e7)
            for key, value in m.Vm.iteritems():
                value.setlb(-1.0)
                value.setub(1e4)
            for key, value in m.Mv.iteritems():
                value.setlb(0.155 + 1e-06)
                value.setub(1e4)
            for key, value in m.Mv1.iteritems():
                value.setlb(8.5 + 1e-06)
                value.setub(1e4)
            for key, value in m.Mvn.iteritems():
                value.setlb(0.17 + 1e-06)
                value.setub(1e4)
            for key, value in m.y.iteritems():
                value.setlb(0.0)
                value.setub(1.0)
            for key, value in m.x.iteritems():
                value.setlb(0.0)
                value.setub(1.0)
            for key, value in m.L.iteritems():
                value.setlb(0.0)
            for key, value in m.V.iteritems():
                value.setlb(0.0)

    _bound_set(m)

    m.Rec = Param(m.fe, initialize=7.72700925775773761472464684629813e-01)
    # m.Rec = Param(m.fe, initialize=0.05)
    m.Qr = Param(m.fe, initialize=1.78604740940007800236344337463379E+06)

    # m.Qr = Param(m.fe, initialize=1.5e+02)

    # mass balances
    def _MODEtr(m, i, j, k):
        if j > 0 and 1 < k < Ntray:
            return 0.0 == (m.V[i, j, k - 1] - m.V[i, j, k] + m.L[i, j, k + 1] -
                           m.L[i, j, k] + m.feed[k])
        else:
            return Constraint.Skip

    m.MODEtr = Constraint(m.fe, m.cp, m.tray, rule=_MODEtr)

    # m.L[i, j, 1] = B
    def _MODEr(m, i, j):
        if j > 0:
            return 0.0 == (m.L[i, j, 2] - m.L[i, j, 1] - m.V[i, j, 1])
        else:
            return Constraint.Skip

    m.MODEr = Constraint(m.fe, m.cp, rule=_MODEr)

    def _MODEc(m, i, j):
        if j > 0:
            return 0.0 == (m.V[i, j, Ntray - 1] - m.L[i, j, Ntray] - m.D[i, j])
        else:
            return Constraint.Skip

    m.MODEc = Constraint(m.fe, m.cp, rule=_MODEc)

    def _XODEtr(m, i, j, t):
        if j > 0 and 1 < t < Ntray:
            return 0.0 == (m.V[i, j, t - 1] * (m.y[i, j, t - 1] - m.x[i, j, t]) + \
                                                     m.L[i, j, t + 1] * (m.x[i, j, t + 1] - m.x[i, j, t]) - \
                                                     m.V[i, j, t] * (m.y[i, j, t] - m.x[i, j, t]) + \
                                                     m.feed[t] * (m.xf - m.x[i, j, t]))
        else:
            return Constraint.Skip

    m.XODEtr = Constraint(m.fe, m.cp, m.tray, rule=_XODEtr)

    def _xoder(m, i, j):
        if j > 0:
            return 0.0 == (m.L[i, j, 2] * (m.x[i, j, 2] - m.x[i, j, 1]) - \
                                                     m.V[i, j, 1] * (m.y[i, j, 1] - m.x[i, j, 1]))
        else:
            return Constraint.Skip

    m.xoder = Constraint(m.fe, m.cp, rule=_xoder)

    def _xodec(m, i, j):
        if j > 0:
            return 0.0 == \
                   (m.V[i, j, Ntray - 1] * (m.y[i, j, Ntray - 1] - m.x[i, j, Ntray]))
        else:
            return Constraint.Skip

    m.xodec = Constraint(m.fe, m.cp, rule=_xodec)

    def _hrc(m, i, j):
        if j > 0:
            return m.D[i, j] - m.Rec[i] * m.L[i, j, Ntray] == 0
        else:
            return Constraint.Skip

    m.hrc = Constraint(m.fe, m.cp, rule=_hrc)

    # Energy balance
    def _gh(m, i, j, t):
        if j > 0 and 1 < t < Ntray:
            return 0.0 \
                   == (m.V[i, j, t-1] * (m.hv[i, j, t-1] - m.hl[i, j, t]) + m.L[i, j, t+1] * (m.hl[i, j, t+1] - m.hl[i, j, t]) - m.V[i, j, t] * (m.hv[i, j, t] - m.hl[i, j, t]) + m.feed[t] * (m.hf - m.hl[i, j, t]))
            # return m.M[i, j, t] * (m.xdot[i, j, t] * ((m.hlm0 - m.hln0) * m.T[i, j, t]**3 + (m.hlma - m.hlna) * m.T[i, j, t]**2 + (m.hlmb - m.hlnb) * m.T[i, j, t] + m.hlmc - m.hlnc) + m.Tdot[i, j, t]*(3*m.hln0*m.T[i, j, t]**2 + 2*m.hlna * m.T[i, j, t] + m.hlnb + m.x[i, j, t]*(3*(m.hlm0 - m.hln0) * m.T[i, j, t]**2 + 2 * (m.hlma - m.hlna) * m.T[i, j, t] + m.hlmb - m.hlnb))) \
            #        M[i, q, c] * (  xdot[i, q, c] * ((  hlm0 -   hln0) *   T[i, q, c] ^ 3 +  (  hlma -   hlna) *   T[i, q, c] ^ 2 +  (  hlmb -   hlnb) *   T[i, q, c] +   hlmc -   hlnc) +   Tdot[i, q, c]*(3*  hln0 * T[i, q, c] ^ 2 +2 * hlna *   T[i, q, c] +   hlnb +   x[i, q, c]*(3*(  hlm0 -   hln0) *   T[i, q, c] ^ 2 +    2 * (  hlma -   hlna) *   T[i, q, c] +   hlmb -   hlnb))) =
            #            V[i - 1, q, c]*(hv[i - 1, q, c] -   hl[i, q, c]) +   L[i + 1, q, c]*(hl[i + 1, q, c] -   hl[i, q, c]) -   V[i, q, c] * (  hv[i, q, c] -   hl[i, q, c]) +   feed[i] * (  hf -   hl[i, q, c]);

        else:
            return Constraint.Skip
        # M[i,q,c]    *(  xdot[i,q,c]*      ((hlm0 -     hln0) *   T[i,q,c]^3 +    (  hlma - hlna)     * T[i,q,c]^2 +    (  hlmb -   hlnb) *   T[i,q,c]   +   hlmc -   hlnc) +   Tdot[i,q,c]  *(3*  hln0*  T[i,q,c]^2    + 2*  hlna*    T[i,q,c] +     hlnb +   x[i,q,c]*  (3*(  hlm0 -   hln0)    *T[i,q,c]^2    + 2*   (hlma  -   hlna)    *T[i,q,c]+      hlmb -   hlnb)))
        # V[i-1,q,c]    *(  hv[i-1,q,c] -     hl[i,q,c]  ) +   L[i+1,q,c]*    (  hl[i+1,q,c] -     hl[i,q,c]  ) -   V[i,q,c]   * (  hv[i,q,c]   -   hl[i,q,c])   +   feed[i] * (hf   -   hl[i,q,c])

    m.gh = Constraint(m.fe, m.cp, m.tray, rule=_gh)

    def _ghb(m, i, j):
        if j > 0:
            return 0.0 == \
                   (m.L[i, j, 2] * (m.hl[i, j, 2] - m.hl[i, j, 1]) - m.V[i, j, 1] * (m.hv[i, j, 1] - m.hl[i, j, 1]) + m.Qr[i])
            #    M[1,q,c]*  (  xdot[1,q,c]  * ((  hlm0 -   hln0)   *T[1,q,c]^3 +    (hlma     - hlna)*  T[1,q,c]^2 +    (  hlmb -   hlnb)  *T[1,q,c]     + hlmc -   hlnc) +   Tdot[1,q,c]*    (3*    hln0 *   T[1,q,c]^2 +   2 *   hlna *   T[1,q,c]   +   hlnb +   x[1,q,c]    * (3 * (  hlm0 -   hln0) *   T[1,q,c]^2    + 2*(  hlma -   hlna)    *T[1,q,c]     + hlmb - hlnb))) =
            #        L[2,q,c]*    (  hl[2,q,c]   -   hl[1,q,c]  ) -   V[1,q,c]   * (  hv[1,q,c]   -   hl[1,q,c]  ) +   Qr[q] ;
        else:
            return Constraint.Skip

    m.ghb = Constraint(m.fe, m.cp, rule=_ghb)

    def _ghc(m, i, j):
        if j > 0:
            return 0.0 == \
                   (m.V[i, j, Ntray - 1] * (m.hv[i, j, Ntray - 1] - m.hl[i, j, Ntray]) - m.Qc[i, j])
            #M[Ntray, q, c] * (xdot[Ntray, q, c]   * ((hlm0 -     hln0) *   T[Ntray, q, c] ^ 3 + (hlma - hlna) * T[Ntray, q, c] ^ 2 +     (hlmb - hlnb) *       T[Ntray, q, c] + hlmc - hlnc) +       Tdot[Ntray, q, c] * (3 * hln0 * T[Ntray, q, c] ^ 2 +    2 * hlna *    T[Ntray, q, c] +   hlnb +   x[Ntray, q, c] * (3 * (  hlm0 -   hln0) * T[Ntray, q, c] ^ 2 + 2 *    (hlma -   hlna) *   T[Ntray, q, c] +   hlmb -   hlnb))) =
            # V[Ntray - 1, q, c] * (hv[Ntray - 1, q, c]     - hl[Ntray, q, c]) -  Qc[q, c];
        else:
            return Constraint.Skip
            #M[Ntray, q, c] * (  xdot[Ntray, q, c] * ((  hlm0 -   hln0) *   T[Ntray, q, c] ^ 3 + (  hlma -   hlna) *  T[Ntray, q, c] ^ 2 +(hlmb   - hlnb) *     T[Ntray, q, c] +   hlmc - hlnc) +     Tdot[Ntray, q, c] * (3 * hln0 * T[Ntray, q, c] ^ 2 + 2 * hlna * T[Ntray, q, c] +         hlnb + x[Ntray, q, c] *   (3 * (  hlm0 -   hln0) * T[Ntray, q, c] ^ 2 + 2 * (hlma - hlna)      *   T[Ntray, q, c] + hlmb     - hlnb))) =
            # V[Ntray - 1, q, c] * (hv[Ntray - 1, q, c] - hl[Ntray, q, c]) - Qc[q, c];

    m.ghc = Constraint(m.fe, m.cp, rule=_ghc)

    def _hkl(m, i, j, t):
        if j > 0:
            return m.hl[i, j, t] == m.x[i, j, t] * (
                m.hlm0 * m.T[i, j, t]**3 + m.hlma * m.T[i, j, t]**2 +
                m.hlmb * m.T[i, j, t] + m.hlmc) + (1 - m.x[i, j, t]) * (
                    m.hln0 * m.T[i, j, t]**3 + m.hlna * m.T[i, j, t]**2 +
                    m.hlnb * m.T[i, j, t] + m.hlnc)


#                    hl[i, q, c] =    x[i, q, c]*(  hlm0 * T[i, q, c] ^ 3 +  hlma * T[i, q, c] ^ 2 + hlmb * T[i, q, c] + hlmc       ) + (1 - x[i, q, c]  )*(  hln0 * T[i, q, c] ^ 3 +    hlna*  T[i, q, c] ^ 2  + hlnb *   T[i, q, c] +   hlnc);
        else:
            return Constraint.Skip
            #    hl[i,q,c]    =   x[i,q,c]*  (  hlm0*  T[i,q,c]^3 +      hlma *   T[i,q,c]^2 +      hlmb*   T[i,q,c] +      hlmc) + (1 - x[i,q,c])*    (  hln0    *T[i,q,c] ^  3 +   hlna*  T[i,q,c]^2 + hlnb         *T[i,q,c]   +   hlnc) ;

    m.hkl = Constraint(m.fe, m.cp, m.tray, rule=_hkl)

    def _hkv(m, i, j, t):
        if j > 0 and t < Ntray:
            return m.hv[i, j, t] == m.y[i, j, t] * (
                m.hlm0 * m.T[i, j, t]**3 + m.hlma * m.T[i, j, t]**2 +
                m.hlmb * m.T[i, j, t] + m.hlmc +
                m.r * m.Tkm * sqrt(1 - (m.p[t] / m.Pkm) *
                                   (m.Tkm / m.T[i, j, t])**3) *
                (m.a - m.b * m.T[i, j, t] / m.Tkm + m.c1 *
                 (m.T[i, j, t] / m.Tkm)**7 + m.gm *
                 (m.d - m.l * m.T[i, j, t] / m.Tkm + m.f *
                  (m.T[i, j, t] / m.Tkm)**7))) + (1 - m.y[i, j, t]) * (
                      m.hln0 * m.T[i, j, t]**3 + m.hlna * m.T[i, j, t]**2 +
                      m.hlnb * m.T[i, j, t] + m.hlnc +
                      m.r * m.Tkn * sqrt(1 - (m.p[t] / m.Pkn) *
                                         (m.Tkn / m.T[i, j, t])**3) *
                      (m.a - m.b * m.T[i, j, t] / m.Tkn + m.c1 *
                       (m.T[i, j, t] / m.Tkn)**7 + m.gn *
                       (m.d - m.l * m.T[i, j, t] / m.Tkn + m.f *
                        (m.T[i, j, t] / m.Tkn)**7)))
        else:
            return Constraint.Skip

    #            hv[i,q,c] =      y[i,q,c]   *     (hlm0 *   T[i,q,c]^3    +   hlma*    T[i,q,c]^2    +   hlmb *   T[i,q,c] +     hlmc +   r*    Tkm*    sqrt(1 - (  p[i]/  Pkm)*  ( Tkm/  T[i,q,c]) ^ 3  )*(a   -   b*    T[i,q,c]/    Tkm +   c1*  (  T[i,q,c]   /  Tkm) ^7 +   gm*  (  d -   l *   T[i,q,c]  /Tkm +     f*(  T[i,q,c] /   Tkm)^7  ))) + (1 - y[i,q,c]    )*  (  hln0 *   T[i,q,c]  ^3 +    hlna*    T[i,q,c]^   2 +   hlnb*    T[i,q,c]  +    hlnc +   r *   Tkn*  sqrt(1 - (  p[i]/Pkn  )*(  Tkn/  T[i,q,c]  )^3 )*(  a -   b *   T[i,q,c]  /  Tkn   + c1 * (  T[i,q,c]  /  Tkn)^7 +    gn*(  d -   l*    T[i,q,c]/    Tkn +    f*(  T[i,q,c]  / Tkn) ^7 ))) ;

    m.hkv = Constraint(m.fe, m.cp, m.tray, rule=_hkv)

    def _lpm(m, i, j, t):
        if j > 0:
            return m.pm[i, j,
                        t] == exp(m.CapAm - m.CapBm / (m.T[i, j, t] + m.CapCm))
        else:
            return Constraint.Skip

    m.lpm = Constraint(m.fe, m.cp, m.tray, rule=_lpm)

    def _lpn(m, i, j, t):
        if j > 0:
            return m.pn[i, j,
                        t] == exp(m.CapAn - m.CapBn / (m.T[i, j, t] + m.CapCn))
        else:
            return Constraint.Skip

    m.lpn = Constraint(m.fe, m.cp, m.tray, rule=_lpn)

    def _dp(m, i, j, t):
        if j > 0:
            return m.p[t] == m.pm[i, j, t] * m.x[i, j, t] + (
                1 - m.x[i, j, t]) * m.pn[i, j, t]
        else:
            return Constraint.Skip

    m.dp = Constraint(m.fe, m.cp, m.tray, rule=_dp)

    def _gy0(m, i, j):
        if j > 0:
            return m.y[i, j, 1] == m.x[i, j, 1] * m.pm[i, j, 1] / m.p[1]
        else:
            return Constraint.Skip

    m.gy0 = Constraint(m.fe, m.cp, rule=_gy0)

    def _gy(m, i, j, t):
        if j > 0 and 1 < t < Ntray:
            return m.y[i, j, t] == m.alpha[t] * m.x[i, j, t] * m.pm[
                i, j, t] / m.p[t] + (1 - m.alpha[t]) * m.y[i, j, t - 1]
            #y[i, q, c] =    alpha[i] *   x[i, q, c] *   pm[i, q, c] /   p[i] + (1 -  alpha[i]) *   y[i - 1, q, c];
        else:
            return Constraint.Skip

    m.gy = Constraint(m.fe, m.cp, m.tray, rule=_gy)

    def _dMV(m, i, j, t):
        if j > 0 and 1 < t < Ntray:
            return m.Mv[i, j, t] == m.Vm[i, j, t] * m.M[i, j, t]
        else:
            return Constraint.Skip

    m.dMV = Constraint(m.fe, m.cp, m.tray, rule=_dMV)

    def _dMv1(m, i, j):
        if j > 0:
            return m.Mv1[i, j] == m.Vm[i, j, 1] * m.M[i, j, 1]
        else:
            return Constraint.Skip

    m.dMv1 = Constraint(m.fe, m.cp, rule=_dMv1)

    def _dMvn(m, i, j):
        if j > 0:
            return m.Mvn[i, j] == m.Vm[i, j, Ntray] * m.M[i, j, Ntray]
        else:
            return Constraint.Skip

    m.dMvn = Constraint(m.fe, m.cp, rule=_dMvn)

    def _hyd(m, i, j, t):
        if j > 0 and 1 < t < Ntray:
            return m.L[i, j, t] * m.Vm[i, j, t] == 0.166 * (m.Mv[i, j, t] -
                                                            0.155)**1.5
            #        L[i,q,c]*      Vm[i,q,c] =    0.166 * (  Mv[i,q,c]   - 0.155)^1.5 ;
        else:
            return Constraint.Skip

    m.hyd = Constraint(m.fe, m.cp, m.tray, rule=_hyd)

    def _hyd1(m, i, j):
        if j > 0:
            return m.L[i, j, 1] * m.Vm[i, j,
                                       1] == 0.166 * (m.Mv1[i, j] - 8.5)**1.5
        else:
            return Constraint.Skip
            #  L[i,q,c]*Vm[i,q,c] = 0.166*(Mv[i,q,c] - 0.155)^1.5 ;

    m.hyd1 = Constraint(m.fe, m.cp, rule=_hyd1)

    def _hydN(m, i, j):
        if j > 0:
            return m.L[i, j, Ntray] * m.Vm[i, j, Ntray] == 0.166 * (
                m.Mvn[i, j] - 0.17)**1.5
        else:
            return Constraint.Skip
            #  L[i,q,c]*Vm[i,q,c] = 0.166*(Mv[i,q,c] - 0.155)^1.5 ;

    m.hydN = Constraint(m.fe, m.cp, rule=_hydN)

    def _dvm(m, i, j, t):
        if j > 0:
            return m.Vm[i, j, t] == m.x[i, j, t] * (
                (1 / 2288) * 0.2685**
                (1 +
                 (1 - m.T[i, j, t] / 512.4)**0.2453)) + (1 - m.x[i, j, t]) * (
                     (1 / 1235) * 0.27136**(1 +
                                            (1 - m.T[i, j, t] / 536.4)**0.24))
        else:
            return Constraint.Skip
            #   Vm[i,q,c] =          x[i,q,c]   * ( 1/2288 *  0.2685^ (1 + (1 -   T[i,q,c]  /512.4)^0.2453)) +   (1 -   x[i,q,c])   * (1/1235 * 0.27136^ (1 + (1 - T[i,q,c]    /536.4)^ 0.24)) ;

    m.dvm = Constraint(m.fe, m.cp, m.tray, rule=_dvm)

    return m
Esempio n. 17
0
    def compile(self, model, start_time):
        """
        Build the structure of the optimization model

        :param model: The entire optimization model
        :param block:The pipe model object
        :param start_time: The optimization start time
        :return:
        """

        Component.compile(self, model, start_time)

        self.history_length = len(self.params['mass_flow_history'].v())
        Tg = self.params['Tg'].v()
        lines = self.params['lines'].v()
        dn = self.params['diameter'].v()
        time_step = self.params['time_step'].v()
        n_steps = int(self.params['horizon'].v() / time_step)

        self.block.all_time = Set(initialize=range(self.history_length +
                                                   n_steps),
                                  ordered=True)

        pipe_wall_rho = 7.85 * 10**3  # http://www.steel-grades.com/Steel-Grades/Structure-Steel/en-p235.html kg/m^3
        pipe_wall_c = 461  # http://www.steel-grades.com/Steel-Grades/Structure-Steel/en-p235.html J/kg/K
        pipe_wall_volume = np.pi * (self.Do[dn]**2 -
                                    self.Di[dn]**2) / 4 * self.length
        C = pipe_wall_volume * pipe_wall_c * pipe_wall_rho
        surface = np.pi * self.Di[dn]**2 / 4  # cross sectional area of the pipe
        Z = surface * self.rho * self.length  # water mass in the pipe

        # TODO Move capacity?

        def _decl_mf(b, t):
            return self.params['mass_flow'].v(t)

        self.block.mass_flow = Param(self.TIME, rule=_decl_mf)

        # Declare temperature variables ################################################################################

        self.block.temperatures = Var(
            lines,
            self.block.all_time)  # all temperatures (historical and future)
        self.block.temperature_out_nhc = Var(
            lines, self.block.all_time)  # no heat capacity (only future)
        self.block.temperature_out_nhl = Var(
            lines, self.block.all_time)  # no heat losses (only future)
        self.block.temperature_out = Var(
            lines, self.block.all_time)  # no heat losses (only future)
        self.block.temperature_in = Var(
            lines, self.block.all_time)  # incoming temperature (future)

        # Declare list filled with all previous mass flows and future mass flows #######################################

        def _decl_mf_history(b, t):
            if t < n_steps:
                return self.block.mass_flow[n_steps - t - 1]
            else:
                return self.params['mass_flow_history'].v(t - n_steps)

        self.block.mf_history = Param(self.block.all_time,
                                      rule=_decl_mf_history)

        # Declare list filled with all previous temperatures for every optimization step ###############################

        def _decl_temp_history(b, t, l):
            if t < n_steps:
                return b.temperatures[l,
                                      t] == b.temperature_in[l,
                                                             n_steps - t - 1]
            else:
                return b.temperatures[l,
                                      t] == self.params['temperature_history_'
                                                        + l].v(t - n_steps)

        self.block.def_temp_history = Constraint(self.block.all_time,
                                                 lines,
                                                 rule=_decl_temp_history)

        # Initialize incoming temperature ##############################################################################

        def _decl_init_temp_in(b, l):
            return b.temperature_in[l, 0] == self.params[
                'temperature_history_' + l].v(
                    0)  # TODO better initialization??

        self.block.decl_init_temp_in = Constraint(lines,
                                                  rule=_decl_init_temp_in)

        # Define n #####################################################################################################

        # Eq 3.4.7
        def _decl_n(b, t):
            sum_m = 0
            for i in range(len(self.block.all_time) - (n_steps - 1 - t)):
                sum_m += b.mf_history[n_steps - 1 - t + i] * time_step
                if sum_m > Z:
                    return i
            self.logger.warning('A proper value for n could not be calculated')
            return i

        self.block.n = Param(self.TIME, rule=_decl_n)

        # Define R #####################################################################################################

        # Eq 3.4.3
        def _decl_r(b, t):
            return sum(self.block.mf_history[i]
                       for i in range(n_steps - 1 - t, n_steps - 1 - t +
                                      b.n[t] + 1)) * time_step

        self.block.R = Param(self.TIME, rule=_decl_r)

        # Define m #####################################################################################################

        # Eq. 3.4.8

        def _decl_m(b, t):
            sum_m = 0
            for i in range(len(self.block.all_time) - (n_steps - 1 - t)):
                sum_m += b.mf_history[n_steps - 1 - t + i] * time_step
                if sum_m > Z + self.block.mass_flow[t] * time_step:
                    return i
            self.logger.warning('A proper value for m could not be calculated')
            return i

        self.block.m = Param(self.TIME, rule=_decl_m)

        # Define Y #####################################################################################################

        # Eq. 3.4.9
        self.block.Y = Var(lines, self.TIME)

        def _y(b, t, l):
            return b.Y[l, t] == sum(
                b.mf_history[i] * b.temperatures[l, i] * time_step
                for i in range(n_steps - 1 - t + b.n[t] + 1, n_steps - 1 - t +
                               b.m[t]))

        self.block.def_Y = Constraint(self.TIME, lines, rule=_y)

        # Define S #####################################################################################################

        # Eq 3.4.10 and 3.4.11
        def _s(b, t):
            if b.m[t] > b.n[t]:
                return sum(b.mf_history[i] * time_step
                           for i in range(n_steps - 1 - t, n_steps - 1 - t +
                                          b.m[t]))

            else:
                return b.R[t]

        self.block.S = Param(self.TIME, rule=_s)

        # Define outgoing temperature, without wall capacity and heat losses ###########################################

        # Eq. 3.4.12
        def _def_temp_out_nhc(b, t, l):
            if b.mass_flow[t] == 0:
                return Constraint.Skip
            else:
                return b.temperature_out_nhc[l, t] == (
                        (b.R[t] - Z) * b.temperatures[
                    l, n_steps - 1 - t + b.n[t]]
                        + b.Y[l, t] + (
                                b.mass_flow[t] * time_step - b.S[t] + Z) *
                        b.temperatures[l, n_steps - 1 - t + b.m[t]]) \
                       / b.mass_flow[t] / time_step

        self.block.def_temp_out_nhc = Constraint(self.TIME,
                                                 lines,
                                                 rule=_def_temp_out_nhc)

        # Pipe wall heat capacity ######################################################################################

        # Eq. 3.4.20
        self.block.K = 1 / self.Rs[self.params['diameter'].v()]

        # Eq. 3.4.14

        self.block.wall_temp = Var(lines, self.TIME)

        def _decl_temp_out_nhl(b, t, l):
            if t == 0:
                return Constraint.Skip
            elif b.mass_flow[t] == 0:
                return Constraint.Skip
            else:
                return b.temperature_out_nhl[l, t] == (
                        b.temperature_out_nhc[l, t] * b.mass_flow[t]
                        * self.cp * time_step
                        + C * b.wall_temp[l, t - 1]) / \
                       (C + b.mass_flow[t] * self.cp * time_step)

        def _temp_wall(b, t, l):
            if b.mass_flow[t] == 0:
                if t == 0:
                    return Constraint.Skip
                else:
                    return b.wall_temp[l, t] == Tg[t] + (
                            b.wall_temp[l, t - 1] - Tg[t]) * \
                           np.exp(-b.K * time_step /
                                  (surface * self.rho * self.cp +
                                   C / self.length))
            else:
                return b.wall_temp[l, t] == b.temperature_out_nhl[l, t]

        # self.block.temp_wall = Constraint(self.TIME, lines, rule=_temp_wall)

        # Eq. 3.4.15

        def _init_temp_wall(b, l):
            return b.wall_temp[l,
                               0] == self.params['wall_temperature_' + l].v()

        self.block.init_temp_wall = Constraint(lines, rule=_init_temp_wall)

        # def _decl_temp_out_nhl(b, t, l):
        #     if t == 0:
        #         return b.temperature_out_nhl[t, l] == (b.temperature_out_nhc[t, l] * (b.mass_flow[t]
        #                                                * self.cp * time_step - C/2)
        #                                                + C * b.wall_temp[t, l]) / \
        #                                           (C/2 + b.mass_flow[t] * self.cp * time_step)
        #     else:
        #         return b.temperature_out_nhl[t, l] == (b.temperature_out_nhc[t, l] * (b.mass_flow[t]
        #                                                * self.cp * time_step - C/2)
        #                                                + C * b.wall_temp[t-1, l]) / \
        #                                               (C/2 + b.mass_flow[t] * self.cp * time_step)

        self.block.decl_temp_out_nhl = Constraint(self.TIME,
                                                  lines,
                                                  rule=_decl_temp_out_nhl)

        # Eq. 3.4.18

        # def _temp_wall(b, t, l):
        #     if t == 0:
        #         return Constraint.Skip
        #     elif b.mass_flow[t] == 0:
        #         return b.wall_temp[t, l] == Tg[t] + (b.wall_temp[t-1, l] - Tg[t]) * \
        #                                     np.exp(-b.K * time_step /
        #                                            (surface * self.rho * self.cp + C/self.length))
        #     else:
        #         return b.wall_temp[t, l] == b.wall_temp[t-1, l] + \
        #                             ((b.temperature_out_nhc[t, l] - b.temperature_out_nhl[t, l]) *
        #                              b.mass_flow[t] * self.cp * time_step) / C

        self.block.temp_wall = Constraint(self.TIME, lines, rule=_temp_wall)

        # Heat losses ##################################################################################################

        # Eq. 3.4.24

        def _tk(b, t):
            if b.mass_flow[t] == 0:
                return Constraint.Skip
            else:
                delta_time = time_step * ((b.R[t] - Z) * b.n[t]
                                          + sum(
                            b.mf_history[n_steps - 1 - t + i] * time_step * i
                            for i in range(b.n[t] + 1, b.m[t]))
                                          + (b.mass_flow[t] * time_step - b.S[
                            t] + Z) * b.m[t]) \
                             / b.mass_flow[t] / time_step
                return delta_time

        self.block.tk = Param(self.TIME, rule=_tk)

        # Eq. 3.4.27

        def _temp_out(b, t, l):
            if b.mass_flow[t] == 0:
                if t == 0:
                    return b.temperature_out[l, t] == self.params[
                        'temperature_out_' + l].v()
                else:
                    return b.temperature_out[l, t] == (
                            b.temperature_out[l, t - 1] - Tg[t]) * \
                           np.exp(-b.K * time_step /
                                  (
                                          surface * self.rho * self.cp + C / self.length)) \
                           + Tg[t]
            else:
                return b.temperature_out[l, t] == Tg[t] + \
                       (b.temperature_out_nhl[l, t] - Tg[t]) * \
                       np.exp(-(b.K * b.tk[t]) /
                              (surface * self.rho * self.cp))

        self.block.def_temp_out = Constraint(self.TIME, lines, rule=_temp_out)
Esempio n. 18
0
def solveropfnlp_4(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

    tr0 = copy(branch[:, TAP])  # transformation ratios
    tr0[find(tr0 == 0)] = 1  # set to 1 transformation ratios that are 0
    tp = find(branch[:, TAP] != 0)  # lines with tap changers
    ntp = find(branch[:, TAP] == 0)  # lines without tap changers

    # Tap changer settings
    dudtap = 0.01  # Voltage per unit variation with tap changes
    tapmax = 10  # Highest tap changer setting
    tapmin = -10  # Lowest tap changer setting

    # Shunt element options
    stepmax = 1  # maximum step of the shunt element

    Bs0 = bus[:, BS] / baseMVA  # shunt elements susceptance
    sd = find(bus[:, BS] != 0)  # buses with shunt devices

    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
    # =============================================================
    # Set tap ratios and shunt elements to neutral position
    branch[:, TAP] = 1
    bus[:, BS] = 0

    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

    # 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
    model.taps = Set(ordered=True,
                     initialize=tp)  # Set of all lines with tap changers
    model.shunt = Set(ordered=True,
                      initialize=sd)  # Set of buses with shunt elements

    # 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)

    # Transformation ratios
    model.tr = Var(model.taps)

    # Tap changer positions + their bounds
    model.tap = Var(model.taps, bounds=(tapmin, tapmax))

    # Shunt susceptance
    model.Bs = Var(model.shunt)

    # Shunt positions + their bounds
    model.s = Var(model.shunt, bounds=(0, stepmax))

    # 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]) / (tr0[i] ** 2) * np.cos(-ang(yft[i])) -\
            vm[fr[i]] * vm[to[i]] * abs(yk[i]) / tr0[i] * np.cos(va[fr[i]] - va[to[i]] - ang(yk[i]))
        model.Qf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr0[i] ** 2) * np.sin(-ang(yft[i])) -\
            vm[fr[i]] * vm[to[i]] * abs(yk[i]) / tr0[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]) / tr0[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]) / tr0[i] * np.sin(va[to[i]] - va[fr[i]] - ang(yk[i]))
    for i in tp:
        model.tr[i] = tr0[i]
    for i in sd:
        model.Bs[i] = Bs0[i]

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

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

    # Active power flow equalities
    def powerflowact(model, i):
        bfrom_i = tp[find(fr[tp] == i)]  # branches from bus i with transformer
        bto_i = tp[find(to[tp] == i)]  # branches to bus i with transformer
        allbut_i = find(bus[:, BUS_I] != i)  # Set of other buses
        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 allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j]**2 - 1) *
                                           np.cos(- ang(yk[j])) for j in bfrom_i) + real(y[i, i]))
        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 allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * cos(model.va[i] -
                       model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j]**2 - 1) *
                                           np.cos(- ang(yk[j])) for j in bfrom_i) + real(y[i, i])) == -Pd[i]

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

    # Reactive power flow equalities
    def powerflowreact(model, i):
        bfrom_i = tp[find(fr[tp] == i)]  # branches from bus i with transformer
        bto_i = tp[find(to[tp] == i)]  # branches to bus i with transformer
        allbut_i = find(bus[:, BUS_I] != i)  # Set of other buses
        sh = sd[find(sd == i)]  # Detect shunt elements
        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 allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * sin(model.va[i] - model.va[to[j]] - ang(yk[j]))
                       * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * sin(model.va[i] - model.va[fr[j]] - ang(yk[j]))
                       * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j] ** 2 - 1) * np.sin(- ang(yk[j]))
                                           for j in bfrom_i) - imag(y[i, i]) - sum(model.Bs[j] for j in sh))
        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 allbut_i) - \
                   sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * sin(model.va[i] -
                       model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                   sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * sin(model.va[i] -
                       model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                   model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j] ** 2 - 1) * np.sin(- ang(yk[j]))
                                           for j in bfrom_i) - imag(y[i, i]) - sum(model.Bs[j] for j in sh)) == - Qd[i]

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

    # Active power from
    def pfrom(model, i):
        if i in tp:
            return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (model.tr[i] ** 2) * np.cos(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / model.tr[i] * \
                                  cos(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))
        else:
            return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / tr0[i] ** 2 * np.cos(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / tr0[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):
        if i in tp:
            return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (model.tr[i] ** 2) * np.sin(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / model.tr[i] * \
                                  sin(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))
        else:
            return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / tr0[i] ** 2 * np.sin(-ang(yft[i])) - \
                                  model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) / tr0[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):
        if i in tp:
            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]) / model.tr[i] * \
                                  cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
        else:
            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]) / tr0[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):
        if i in tp:
            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]) / model.tr[i] * \
                                  sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
        else:
            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]) / tr0[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)

    # Transformation ratio equalities
    def trfunc(model, i):
        return model.tr[i] == 1 + dudtap * model.tap[i]

    model.const8 = Constraint(model.taps, rule=trfunc)

    # Shunt susceptance equality
    def shuntfunc(model, i):
        return model.Bs[i] == model.s[i] / stepmax * Bs0[i]

    model.const9 = Constraint(model.shunt, rule=shuntfunc)

    # 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.const10 = 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.const11 = Constraint(model.gen, rule=genqlimits)

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

    model.const12 = 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.const13 = 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.const14 = Constraint(model.line, rule=stomax)

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

    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 and approximate the continuous variables to discrete values
    # ==============================================================================================================
    for i in range(nb):
        if i in sd:
            bus[i, BS] = round(model.s[i].value) * Bs0[i] * baseMVA
        bus[i, VM] = model.vm[i].value  # Bus voltage magnitudes
        bus[i, VA] = model.va[i].value * 180 / pi  # Bus voltage angles
    # Update transformation ratios
    for i in range(nl):
        if i in tp:
            branch[i, TAP] = 1 + dudtap * round(model.tap[i].value)
    # 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:]
    branch[:, 0:2] = ppc['branch'][:, 0:2]
    ppc['branch'] = branch
    ppc['gen'][:, 1:] = gen[:, 1:]

    # Execute a second optimization with only the discrete approximated values (requires solveropfnlp_2)
    sol = solveropfnlp_2(ppc)
    sol['mt'] = sol['mt'] + mt
    sol['et'] = sol['et'] + et
    sol['tap'] = zeros((tp.shape[0], 1))
    for i in range(tp.shape[0]):
        sol['tap'][i] = round(model.tap[tp[i]].value)
    sol['shunt'] = zeros((sd.shape[0], 1))
    for i in range(sd.shape[0]):
        sol['shunt'][i] = round(model.s[sd[i]].value)

    # ppc solved case is returned
    return sol
Esempio n. 19
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))
Esempio n. 20
0
    def __init__(self, **kwargs):
        NmpcGen.__init__(self, **kwargs)
        self.int_file_mhe_suf = int(time.time())-1

        # Need a list of relevant measurements y

        self.y = kwargs.pop('y', [])
        self.y_vars = kwargs.pop('y_vars', {})

        # Need a list or relevant noisy-states z

        self.x_noisy = kwargs.pop('x_noisy', [])
        self.x_vars = kwargs.pop('x_vars', {})
        self.deact_ics = kwargs.pop('del_ics', True)
        self.diag_Q_R = kwargs.pop('diag_QR', True)  #: By default use diagonal matrices for Q and R matrices
        self.u = kwargs.pop('u', [])
        self.IgnoreProcessNoise = kwargs.pop('IgnoreProcessNoise', False)


        print("-" * 120)
        print("I[[create_lsmhe]] lsmhe (full) model created.")
        print("-" * 120)
        nstates = sum(len(self.x_vars[x]) for x in self.x_noisy)

        self.journalizer("I", self._c_it, "MHE with \t", str(nstates) + "states")
        self.journalizer("I", self._c_it, "MHE with \t", str(nstates*self.nfe_t*self.ncp_t) + "noise vars")
        self.lsmhe = self.d_mod(self.nfe_t, self.ncp_t, _t=self._t)
        self.lsmhe.name = "LSMHE (Least-Squares MHE)"
        self.lsmhe.create_bounds()
        #: create x_pi constraint

        #: Create list of noisy-states vars
        self.xkN_l = []
        self.xkN_nexcl = []
        self.xkN_key = {}
        k = 0
        for x in self.x_noisy:
            n_s = getattr(self.lsmhe, x)  #: Noisy-state
            for jth in self.x_vars[x]:  #: the jth variable
                self.xkN_l.append(n_s[(1, 0) + jth])
                self.xkN_nexcl.append(1)  #: non-exclusion list for active bounds
                self.xkN_key[(x, jth)] = k
                k += 1

        self.lsmhe.xkNk_mhe = Set(initialize=[i for i in range(0, len(self.xkN_l))])  #: Create set of noisy_states
        self.lsmhe.x_0_mhe = Param(self.lsmhe.xkNk_mhe, initialize=0.0, mutable=True)  #: Prior-state
        self.lsmhe.wk_mhe = Param(self.lsmhe.fe_t, self.lsmhe.cp_ta, self.lsmhe.xkNk_mhe, initialize=0.0) \
            if self.IgnoreProcessNoise else Expression(self.lsmhe.fe_t, self.lsmhe.cp_ta, self.lsmhe.xkNk_mhe)  #: Model disturbance
        self.lsmhe.PikN_mhe = Param(self.lsmhe.xkNk_mhe, self.lsmhe.xkNk_mhe,
                                initialize=lambda m, i, ii: 1. if i == ii else 0.0, mutable=True)  #: Prior-Covariance
        self.lsmhe.Q_mhe = Param(range(1, self.nfe_t), self.lsmhe.xkNk_mhe, initialize=1, mutable=True) if self.diag_Q_R\
            else Param(range(1, self.nfe_t), self.lsmhe.xkNk_mhe, self.lsmhe.xkNk_mhe,
                             initialize=lambda m, t, i, ii: 1. if i == ii else 0.0, mutable=True)  #: Disturbance-weight
        j = 0
        for i in self.x_noisy:
            de_exp = getattr(self.lsmhe, "de_" + i)
            for k in self.x_vars[i]:
                for tfe in range(1, self.nfe_t+1):
                    for tcp in range(1, self.ncp_t + 1):
                        self.lsmhe.wk_mhe[tfe, tcp, j].set_value(de_exp[(tfe, tcp) + k]._body)
                        de_exp[(tfe, tcp) + k].deactivate()
                j += 1



        #: Create list of measurements vars
        self.yk_l = {}
        self.yk_key = {}
        k = 0
        self.yk_l[1] = []
        for y in self.y:
            m_v = getattr(self.lsmhe, y)  #: Measured "state"
            for jth in self.y_vars[y]:  #: the jth variable
                self.yk_l[1].append(m_v[(1, self.ncp_t) + jth])
                self.yk_key[(y, jth)] = k  #: The key needs to be created only once, that is why the loop was split
                k += 1

        for t in range(2, self.nfe_t + 1):
            self.yk_l[t] = []
            for y in self.y:
                m_v = getattr(self.lsmhe, y)  #: Measured "state"
                for jth in self.y_vars[y]:  #: the jth variable
                    self.yk_l[t].append(m_v[(t, self.ncp_t) + jth])

        self.lsmhe.ykk_mhe = Set(initialize=[i for i in range(0, len(self.yk_l[1]))])  #: Create set of measured_vars
        self.lsmhe.nuk_mhe = Var(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, initialize=0.0)   #: Measurement noise
        self.lsmhe.yk0_mhe = Param(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, initialize=1.0, mutable=True)
        self.lsmhe.hyk_c_mhe = Constraint(self.lsmhe.fe_t, self.lsmhe.ykk_mhe,
                                          rule=
                                          lambda mod, t, i:mod.yk0_mhe[t, i] - self.yk_l[t][i] - mod.nuk_mhe[t, i] == 0.0)
        self.lsmhe.hyk_c_mhe.deactivate()
        self.lsmhe.R_mhe = Param(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, initialize=1.0, mutable=True) if self.diag_Q_R else \
            Param(self.lsmhe.fe_t, self.lsmhe.ykk_mhe, self.lsmhe.ykk_mhe,
                             initialize=lambda mod, t, i, ii: 1.0 if i == ii else 0.0, mutable=True)
        f = open("file_cv.txt", "w")
        f.close()

        #: Constraints for the input noise
        for u in self.u:
            # cv = getattr(self.lsmhe, u)  #: Get the param
            # c_val = [value(cv[i]) for i in cv.keys()]  #: Current value
            # self.lsmhe.del_component(cv)  #: Delete the param
            # self.lsmhe.add_component(u + "_mhe", Var(self.lsmhe.fe_t, initialize=lambda m, i: c_val[i-1]))
            self.lsmhe.add_component("w_" + u + "_mhe", Var(self.lsmhe.fe_t, initialize=0.0))  #: Noise for input
            self.lsmhe.add_component("w_" + u + "c_mhe", Constraint(self.lsmhe.fe_t))
            self.lsmhe.equalize_u(direction="r_to_u")
            # cc = getattr(self.lsmhe, u + "_c")  #: Get the constraint for input
            con_w = getattr(self.lsmhe, "w_" + u + "c_mhe")  #: Get the constraint-noisy
            var_w = getattr(self.lsmhe, "w_" + u + "_mhe")  #: Get the constraint-noisy
            ce = getattr(self.lsmhe, u + "_e")  #: Get the expression
            cp = getattr(self.lsmhe, u)  #: Get the param

            con_w.rule = lambda m, i: cp[i] == ce[i] + var_w[i]
            con_w.reconstruct()
            con_w.deactivate()

            # con_w.rule = lambda m, i: cp[i] == cv[i] + var_w[i]
            # con_w.reconstruct()
            # with open("file_cv.txt", "a") as f:
            #     cc.pprint(ostream=f)
            #     con_w.pprint(ostream=f)
                # f.close()

        self.lsmhe.U_mhe = Param(range(1, self.nfe_t + 1), self.u, initialize=1, mutable=True)

        #: Deactivate icc constraints
        if self.deact_ics:
            pass
            # for i in self.states:
            #     self.lsmhe.del_component(i + "_icc")
        #: Maybe only for a subset of the states
        else:
            for i in self.states:
                if i in self.x_noisy:
                    ic_con = getattr(self.lsmhe, i + "_icc")
                    for k in self.x_vars[i]:
                        ic_con[k].deactivate()

        #: Put the noise in the continuation equations (finite-element)
        j = 0
        self.lsmhe.noisy_cont = ConstraintList()
        for i in self.x_noisy:
            # cp_con = getattr(self.lsmhe, "cp_" + i)
            cp_exp = getattr(self.lsmhe, "noisy_" + i)
            # self.lsmhe.del_component(cp_con)
            for k in self.x_vars[i]:  #: This should keep the same order
                for t in range(1, self.nfe_t):
                    self.lsmhe.noisy_cont.add(cp_exp[t, k] == 0.0)
                    # self.lsmhe.noisy_cont.add(cp_exp[t, k] == 0.0)
                j += 1
            # cp_con.reconstruct()
        j = 0
        self.lsmhe.noisy_cont.deactivate()

        #: Expressions for the objective function (least-squares)
        self.lsmhe.Q_e_mhe = 0.0 if self.IgnoreProcessNoise else Expression(
            expr=0.5 * sum(
                sum(
                    sum(self.lsmhe.Q_mhe[1, k] * self.lsmhe.wk_mhe[i, j, k]**2 for k in self.lsmhe.xkNk_mhe) for j in range(1, self.ncp_t +1))
                for i in range(1, self.nfe_t+1))) if self.diag_Q_R else Expression(
            expr=sum(sum(self.lsmhe.wk_mhe[i, j] *
                         sum(self.lsmhe.Q_mhe[i, j, k] * self.lsmhe.wk_mhe[i, 1, k] for k in self.lsmhe.xkNk_mhe)
                         for j in self.lsmhe.xkNk_mhe) for i in range(1, self.nfe_t)))

        self.lsmhe.R_e_mhe = Expression(
            expr=0.5 * sum(
                sum(
                    self.lsmhe.R_mhe[i, k] * self.lsmhe.nuk_mhe[i, k]**2 for k in self.lsmhe.ykk_mhe)
                for i in self.lsmhe.fe_t)) if self.diag_Q_R else Expression(
            expr=sum(sum(self.lsmhe.nuk_mhe[i, j] *
                         sum(self.lsmhe.R_mhe[i, j, k] * self.lsmhe.nuk_mhe[i, k] for k in self.lsmhe.ykk_mhe)
                         for j in self.lsmhe.ykk_mhe) for i in self.lsmhe.fe_t))
        expr_u_obf = 0
        for i in self.lsmhe.fe_t:
            for u in self.u:
                var_w = getattr(self.lsmhe, "w_" + u + "_mhe")  #: Get the constraint-noisy
                expr_u_obf += self.lsmhe.U_mhe[i, u] * var_w[i] ** 2

        self.lsmhe.U_e_mhe = Expression(expr=0.5 * expr_u_obf)  # how about this
        # with open("file_cv.txt", "a") as f:
        #     self.lsmhe.U_e_mhe.pprint(ostream=f)
        #     f.close()

        self.lsmhe.Arrival_e_mhe = Expression(
            expr=0.5 * sum((self.xkN_l[j] - self.lsmhe.x_0_mhe[j]) *
                     sum(self.lsmhe.PikN_mhe[j, k] * (self.xkN_l[k] - self.lsmhe.x_0_mhe[k]) for k in self.lsmhe.xkNk_mhe)
                     for j in self.lsmhe.xkNk_mhe))

        self.lsmhe.Arrival_dummy_e_mhe = Expression(
            expr=100000.0 * sum((self.xkN_l[j] - self.lsmhe.x_0_mhe[j]) ** 2 for j in self.lsmhe.xkNk_mhe))

        self.lsmhe.obfun_dum_mhe_deb = Objective(sense=minimize,
                                             expr=self.lsmhe.Q_e_mhe)
        self.lsmhe.obfun_dum_mhe = Objective(sense=minimize,
                                             expr=self.lsmhe.R_e_mhe + self.lsmhe.Q_e_mhe + self.lsmhe.U_e_mhe) # no arrival
        self.lsmhe.obfun_dum_mhe.deactivate()

        self.lsmhe.obfun_mhe_first = Objective(sense=minimize,
                                         expr=self.lsmhe.Arrival_dummy_e_mhe + self.lsmhe.Q_e_mhe)
        self.lsmhe.obfun_mhe_first.deactivate()


        self.lsmhe.obfun_mhe = Objective(sense=minimize,
                                         expr=self.lsmhe.Arrival_dummy_e_mhe + self.lsmhe.R_e_mhe + self.lsmhe.Q_e_mhe + self.lsmhe.U_e_mhe)
        self.lsmhe.obfun_mhe.deactivate()

        # with open("file_cv.txt", "a") as f:
        #     self.lsmhe.obfun_mhe.pprint(ostream=f)
        #     f.close()

        self._PI = {}  #: Container of the KKT matrix
        self.xreal_W = {}
        self.curr_m_noise = {}   #: Current measurement noise
        self.curr_y_offset = {}  #: Current offset of measurement
        for y in self.y:
            for j in self.y_vars[y]:
                self.curr_m_noise[(y, j)] = 0.0
                self.curr_y_offset[(y, j)] = 0.0

        self.s_estimate = {}
        self.s_real = {}
        for x in self.x_noisy:
            self.s_estimate[x] = []
            self.s_real[x] = []

        self.y_estimate = {}
        self.y_real = {}
        self.y_noise_jrnl = {}
        self.yk0_jrnl = {}
        for y in self.y:
            self.y_estimate[y] = []
            self.y_real[y] = []
            self.y_noise_jrnl[y] = []
            self.yk0_jrnl[y] = []
Esempio n. 21
0
    def __init__(
        self,
        data,
        target,
        number_regions,
        lam,
        epsilon=0.01,
        f_star=None,
        selected_features=None,
    ):
        super().__init__(
            name="OplraRegression %d regions (f*=%s)" % (number_regions, f_star)
        )
        self.number_regions = number_regions

        # Data and parameters
        self.data = data
        self.target = target
        self.lam = lam
        self.U1 = 1.5
        self.U2 = sum(self.target)
        self.epsilon = epsilon

        # Indices of the model
        self.s = Set(initialize=data.index.tolist())
        self.r = Set(initialize=range(self.number_regions))
        if self.number_regions == 1 or selected_features is None:
            self.f = Set(initialize=self.data.columns, ordered=True)
        else:
            self.f = Set(initialize=selected_features, ordered=True)

        # Variables common to both FEATURE_SELECTION and PIECEWISE models
        self.W = Var(self.r, self.f, initialize=0)

        self.absW = Var(self.r, self.f, domain=NonNegativeReals, initialize=0)
        self.B = Var(self.r, initialize=0)
        self.Pred = Var(self.r, self.s, initialize=0)
        self.D = Var(self.s, domain=NonNegativeReals, initialize=0)
        self.F = Var(self.r, self.s, domain=Binary, initialize=0)
        self.z = Var(domain=NonNegativeReals, initialize=0)
        self.mae = Var(domain=NonNegativeReals, initialize=0)
        self.reg = Var(domain=NonNegativeReals, initialize=0)

        if self.number_regions > 1 and f_star is None:
            raise ValueError("f_star is invalid.")

        self.fStar = f_star

        # Specific variables and constraints according to model (number of regions)
        if self.number_regions == 1:
            self.sf = Var(self.f, domain=Binary, initialize=0)
            # Old equations used for explicit feature selection
            # self.number_features    = Constraint(rule=OplraPyomoModel.number_features_rule)
            # self.upper_bound_coeff  = Constraint(self.r, self.f, rule=OplraPyomoModel.upper_bound_coeff_rule)
            # self.lower_bound_coeff  = Constraint(self.r, self.f, rule=OplraPyomoModel.lower_bound_coeff_rule)
        else:
            self.isSimpleLinear = False
            self.fStar = self.fStar
            self.X = Var(self.r, bounds=(0.0, 1.0), initialize=0)
            self.rr = Set(within=self.r)
            self.breakpoint_order = Constraint(
                self.r, rule=OplraPyomoModel.breakpoint_order_rule
            )
            self.region_divider1 = Constraint(
                self.r, self.s, rule=OplraPyomoModel.region_divider1_rule
            )
            self.region_divider2 = Constraint(
                self.r, self.s, rule=OplraPyomoModel.region_divider2_rule
            )

        # Common constraints
        self.sample_to_region = Constraint(
            self.s, rule=OplraPyomoModel.sample_to_region_rule
        )
        self.prediction = Constraint(
            self.r, self.s, rule=OplraPyomoModel.prediction_rule
        )
        self.abs_error1 = Constraint(
            self.r, self.s, rule=OplraPyomoModel.abs_error1_rule
        )
        self.abs_error2 = Constraint(
            self.r, self.s, rule=OplraPyomoModel.abs_error2_rule
        )
        self.abs_coeff1 = Constraint(
            self.r, self.f, rule=OplraPyomoModel.abs_coeff1_rule
        )
        self.abs_coeff2 = Constraint(
            self.r, self.f, rule=OplraPyomoModel.abs_coeff2_rule
        )
        self.mae_eqn = Constraint(rule=OplraPyomoModel.mae_rule)
        self.reg_eqn = Constraint(rule=OplraPyomoModel.regularisation_rule)
        self.z_eqn = Constraint(rule=OplraPyomoModel.z_rule)
        self.obj = Objective(rule=OplraPyomoModel.objective_rule, sense=minimize)
Esempio n. 22
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
Esempio n. 23
0
    def set_external_model(
        self,
        external_grey_box_model,
        inputs=None,
        outputs=None,
    ):
        """
        Parameters
        ----------
        external_grey_box_model: ExternalGreyBoxModel
            The external model that will be interfaced to in this block
        inputs: List of VarData objects
            If provided, these VarData will be used as inputs into the
            external model.
        outputs: List of VarData objects
            If provided, these VarData will be used as outputs from the
            external model.

        """
        self._ex_model = ex_model = external_grey_box_model
        if ex_model is None:
            self._input_names = self._output_names = None
            self.inputs = self.outputs = None
            return

        # Shouldn't need input names if we provide input vars, but
        # no reason to remove this.
        # _could_ make inputs a reference-to-mapping
        self._input_names = ex_model.input_names()
        if self._input_names is None or len(self._input_names) == 0:
            raise ValueError(
                'No input_names specified for external_grey_box_model.'
                ' Must specify at least one input.')

        self._input_names_set = Set(initialize=self._input_names, ordered=True)

        if inputs is None:
            self.inputs = Var(self._input_names_set)
        else:
            if ex_model.n_inputs() != len(inputs):
                raise ValueError(
                    "Dimension mismatch in provided input vars for external "
                    "model.\nExpected %s input vars, got %s." %
                    (ex_model.n_inputs(), len(inputs)))
            self.inputs = Reference(inputs)

        self._equality_constraint_names = ex_model.equality_constraint_names()
        self._output_names = ex_model.output_names()

        self._output_names_set = Set(initialize=self._output_names,
                                     ordered=True)

        if outputs is None:
            self.outputs = Var(self._output_names_set)
        else:
            if ex_model.n_outputs() != len(outputs):
                raise ValueError(
                    "Dimension mismatch in provided output vars for external "
                    "model.\nExpected %s output vars, got %s." %
                    (ex_model.n_outputs(), len(outputs)))
            self.outputs = Reference(outputs)

        # call the callback so the model can set initialization, bounds, etc.
        external_grey_box_model.finalize_block_construction(self)
Esempio n. 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)
     #
     # 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
Esempio n. 25
0
def set_testl(market_instances_list, airport_list, market_data,
              segment_travel_time, time_zone_dict, iti_dict, fleet_data,
              passeger_type_dict, attr_value, marketpt_attr_sum, solver):
    """
    很多输入变量都是字典,就是为了在模型中生成子集的时候有筛选功能 即 if dict【m】 in dict 
    :param airport_list: 
    :param market_data: 
    :param segment_travel_time: 
    :param iti_dict:itinerary number key ,info value :{0: {'market': "M('SEA', 'LAX')", 'non_stop': ('SEA', 'LAX'), ('SEA', 'LAX'): 1, 'legs': [('SEA', 'LAX')]}
    :param fleet_data: 
    :param passeger_type_dict: passenger_type as key , and it's proportions
    :param attr_value: 
    :param marketpt_attr_sum: 
    :param solver: 
    :return: time_table, q_variable for each itinerary, 
    """
    market_iti = {}  #market:itinerary list
    for m in market_instances_list:
        l = [
            i for i, v in iti_dict.items()
            if v['market'] == 'M' + str(m.od_pair)
        ]
        market_iti.update({m: l})
    model = ConcreteModel()
    market = list(market_data.keys())  #['M' + str(m.od_pair) for m in ]
    # market_segment={m:[(market_data[m][4],market_data[m][5])] for m in market_data.keys()}
    model.M = Set(initialize=market, doc='Player Market_obj')
    model.Mi = Set(list(market_iti.keys()),
                   initialize=market_iti,
                   doc='Player Market_obj')
    model.AP = Set(initialize=airport_list)
    model.Segment = Set(initialize=((i, j) for i in model.AP for j in model.AP
                                    if i != j))

    # create time spot [1-72] and it's time
    a = np.linspace(1, int((1440 - 360) / 15), int((1440 - 360) / 15))
    time_list = np.arange(360, 1440, 15)
    time_dict = dict(zip(a, time_list))
    # reverse_time_dict = {v: k for k, v in time_dict.items()}
    model.T = Set(
        initialize=a,
        ordered=True,
        doc='Time period from 300 min to 1440 ,step :15min,number:73')
    model.I = Set(initialize=iti_dict.keys(), doc='itinerary _index,size 4334')
    model.Im = Set(initialize=((m, i) for m in model.M for i in market_iti[m]),
                   doc='tuple(m,i),size 4334')  # 筛选出只在m的itinerary 的 号码
    model.PT = Set(initialize=passeger_type_dict.keys())
    model.F = Set(initialize=fleet_data.keys())
    d = {}  #create a dict as which OD and time get all itinerary_index in it
    for ap1, ap2 in model.Segment:
        for t in model.T:
            v = []
            for i, va in iti_dict.items():
                if (ap1, ap2) in va['legs'] and t == va[(ap1, ap2)]:
                    v.append(i)
            d[(ap1, ap2, t)] = v
    model.St = Set(
        list(d.keys()),
        initialize=d)  # index as (ap1,ap2,time) get [itinerary index list]

    def _filter3(model, i, m, ap1, ap2, t):

        return i in model.Mi[m].value and i in model.St[(ap1, ap2, t)].value

    # def Parameters
    demand_pt = {
    }  # get demand of pt in the market by total demand times its proportion
    print("passenger_type_proportion:", passeger_type_dict)
    for m, va in market_data.items():
        for ty, rato in passeger_type_dict.items():
            demand_pt.update({(m, ty):
                              va[0] * rato})  # market demand times proportions
    model.Dem = Param(model.M,
                      model.PT,
                      initialize=demand_pt,
                      doc='Market demand for each type of passenger')

    price_dict = {}
    for i in model.I:
        rato = np.linspace(1.3, 0.7, len(passeger_type_dict))
        for index, ty in enumerate(passeger_type_dict):
            if iti_dict[i]['non_stop']:
                price_dict.update({
                    (i, ty):
                    market_data[iti_dict[i]['market']][2] * rato[index]
                })  # market_data[m][2] is price
            else:
                price_dict.update({
                    (i, ty):
                    0.8 * market_data[iti_dict[i]['market']][2] * rato[index]
                })  # market_data[m][2] is price
    model.p = Param(model.I, model.PT, initialize=price_dict)
    model.Avail = Param(
        model.F,
        initialize={fleet: value[0]
                    for fleet, value in fleet_data.items()})
    model.Cap = Param(
        model.F,
        initialize={fleet: value[1]
                    for fleet, value in fleet_data.items()})
    model.distance = Param(model.Segment,
                           initialize={(value[-2], value[-1]): value[1]
                                       for value in market_data.values()})

    def ope_cost(model, ap1, ap2, f):
        if model.distance[ap1, ap2] <= 3106:
            return (1.6 * model.distance[ap1, ap2] + 722) * (model.Cap[f] +
                                                             104) * 0.019
        else:
            return (1.6 * model.distance[ap1, ap2] + 2200) * (model.Cap[f] +
                                                              211) * 0.0115

    model.Ope = Param(model.Segment, model.F, initialize=ope_cost, doc='cost')
    freq = {(market_data[m][4], market_data[m][5]): market_data[m][3]
            for m in market_data.keys()}

    model.Freq = Param(model.Segment, initialize=freq)
    model.A = Param(model.I, model.PT, initialize=attr_value)

    model.Am = Param(model.M, model.PT, initialize=marketpt_attr_sum)
    # Step 2: Define decision variables
    model.x = Var(model.Segment, model.F, model.T, within=Binary)
    model.y_1 = Var(model.F, model.AP, model.T, within=PositiveIntegers)
    model.y_2 = Var(model.F, model.AP, model.T, within=PositiveIntegers)
    model.q = Var(model.I, model.PT, within=NonNegativeReals)
    model.non_q = Var(model.M, model.PT, within=NonNegativeReals
                      )  # number of pax that choose others airine and no fly.

    # Step 3: Define Objective
    def obj_rule(model):
        return sum(model.q[i, pt] * model.p[i, pt] for i in model.I
                   for pt in model.PT) - sum(model.Ope[s, f] * model.x[s, f, t]
                                             for s in model.Segment
                                             for f in model.F for t in model.T)

    model.obj = Objective(rule=obj_rule, sense=maximize)

    def obj_cost(model):
        return sum(model.Ope[s, f] * model.x[s, f, t] for s in model.Segment
                   for f in model.F for t in model.T)

    model.obj_cost = Expression(rule=obj_cost)

    def obj_revenue(model):
        return sum(model.q[i, pt] * model.p[i, pt] for i in model.I
                   for pt in model.PT)

    model.obj_revenue = Expression(rule=obj_revenue)

    # add constraint
    # Aircraft count:
    def aircraft_con(model, f):
        return sum(model.y_1[f, ap, model.T[1]]
                   for ap in model.AP) <= model.Avail[f]

    model.count = Constraint(model.F, rule=aircraft_con)

    # flow balance cons
    def flow_balance_1(model, f, ap):
        return model.y_1[f, ap, model.T[1]] == model.y_2[f, ap, model.T[-1]]

    model.con_fb_1 = Constraint(model.F, model.AP, rule=flow_balance_1)

    def flow_balance_2(model, f, ap, t):
        # if t == model.T[-1]:
        #     return Constraint.Skip
        # else:
        return model.y_1[f, ap, t + 1] == model.y_2[f, ap, t]

    def filter2(model, t):
        return t != model.T[-1]

    model.Tm = Set(initialize=(i for i in model.T if i != model.T[-1]))
    #model.con_fb_2 = Constraint(model.F, model.AP, model.T, rule=flow_balance_2)
    model.con_fb_2 = Constraint(model.F,
                                model.AP,
                                model.Tm,
                                rule=flow_balance_2)
    # time_zone_dict={('ANC', 'PDX'): 60, ('SEA', 'PDX'): 0, ('SEA', 'ANC'): -60, ('ANC', 'LAX'): 60, ('PDX', 'SEA'): 0, ('LAX', 'PDX'): 0,
    #                 ('LAX', 'SEA'): 0, ('PDX', 'ANC'): -60, ('SEA', 'LAX'): 0, ('ANC', 'SEA'): 60, ('LAX', 'ANC'): -60, ('PDX', 'LAX'): 0}

    Travel_time = segment_travel_time

    def flow_balance_3(model, f, ap, t):
        def D(s, t, turnaround=30):
            arrival_time = time_dict[t]
            dep_time = arrival_time - (Travel_time[s] +
                                       turnaround) - time_zone_dict[s]
            if dep_time >= 360:
                t0 = ((dep_time - 360) // 15) + 1
            else:
                t0 = 72 - (abs(360 - dep_time) // 15)
            return t0

        return model.y_1[f, ap, t] + sum(
            model.x[s, f, D(s, t)]
            for s in model.Segment if s[1] == ap) == model.y_2[f, ap, t] + sum(
                model.x[s, f, t] for s in model.Segment if s[0] == ap)

    model.con_fb_3 = Constraint(model.F,
                                model.AP,
                                model.T,
                                rule=flow_balance_3)

    # Demand and capacity constrains:
    def attract_con(model, market, i, pt):
        return model.Am[market, pt] * (
            model.q[i, pt] / model.Dem[market, pt]) <= model.A[i, pt] * (
                model.non_q[market, pt] / model.Dem[market, pt])

    model.attractiveness = Constraint(model.Im, model.PT, rule=attract_con)

    def capacity_con(model, ap1, ap2, t):
        return sum(model.q[i, pt] for i in d[(ap1, ap2, t)]
                   for pt in model.PT) <= sum(
                       model.Cap[f] * model.x[ap1, ap2, f, t] for f in model.F)

    model.con_d1 = Constraint(model.Segment, model.T, rule=capacity_con)

    def demand_market_con(model, market, pt):
        return sum(model.q[i, pt] for i in model.I if iti_dict[i]['market'] == market) + model.non_q[market, pt] == \
               model.Dem[market, pt]

    model.con_d3 = Constraint(model.M, model.PT, rule=demand_market_con)

    # Itinerary selection constraints:
    model.AC = Set(initialize=model.I * model.M * model.Segment * model.T,
                   filter=_filter3)

    def iti_selection(model, i, m, ap1, ap2, t, pt):
        # if i in market_iti[m] and i in d[(ap1, ap2, t)]:
        return sum(model.x[ap1, ap2, f, t]
                   for f in model.F) >= model.q[i, pt] / model.Dem[m, pt]

    model.con_iti_selection = Constraint(model.AC,
                                         model.PT,
                                         rule=iti_selection)

    # Restrictions on fight leg variables:
    def flight_leg_con(model, ap1, ap2, t):
        return sum(model.x[ap1, ap2, f, t] for f in model.F) <= 1

    model.con_leg_1 = Constraint(model.Segment, model.T, rule=flight_leg_con)

    def freq_con(model, ap1, ap2):
        return sum(model.x[ap1, ap2, f, t] for t in model.T
                   for f in model.F) == model.Freq[ap1, ap2]

    model.con_let_2 = Constraint(model.Segment, rule=freq_con)
    print("____" * 5)
    # for con in model.component_map(Constraint).itervalues():
    #     con.pprint()

    SOLVER_NAME = solver
    TIME_LIMIT = 60 * 60 * 2
    results = SolverFactory(SOLVER_NAME)

    if SOLVER_NAME == 'cplex':
        results.options['timelimit'] = TIME_LIMIT
    elif SOLVER_NAME == 'glpk':
        results.options['tmlim'] = TIME_LIMIT
    elif SOLVER_NAME == 'gurobi':
        results.options['TimeLimit'] = TIME_LIMIT

    com = results.solve(model, tee=True)
    com.write()

    #absgap = com.solution(0).gap
    # get x results in matrix form
    df_x = pd.DataFrame(columns=list(model.Segment), index=model.T)
    for s in model.Segment:
        for t in model.T:
            for f in model.F:
                if model.x[s, f, t].value > 0:
                    df_x.loc[t, [s]] = f

    #df_x=df_x.reset_index()# return value  is a dataframe of new time table
    # 所有的决策变量都遍历一遍
    # for v in instance.component_objects(Var, active=True):
    #     print("Variable", v)
    #     varobject = getattr(instance, str(v))
    #     for index in varobject:
    #         print("   ", index, varobject[index].value)
    varobject = getattr(model, 'q')
    q_data = {(i, pt): varobject[(i, pt)].value
              for (i, pt), v in varobject.items() if varobject[(i, pt)] != 0}
    df_q = pd.DataFrame.from_dict(q_data,
                                  orient="index",
                                  columns=["variable value"])
    varobject2 = getattr(model, 'non_q')
    nonq_data = {(m, pt): varobject2[(m, pt)].value
                 for (m, pt), v in varobject2.items()
                 if varobject2[(m, pt)] != 0}

    # q = list(model.q.get_values().values())
    # print('q = ', q)
    profit = model.obj()
    print('\nProfit = ', profit)
    cost = value_s(model.obj_cost())
    #revenue=value_s(model.obj_revenue())
    print('cost is:' * 10, cost)
    #print('revenue is:' * 10, revenue)
    '''
    print('\nDecision Variables')
    #list_of_vars = [v.value for v in model.component_objects(ctype=Var, active=True, descend_into=True)]
    #var_names = [v.name for v in model.component_objects(ctype=Var, active=True, descend_into=True) if v.value!=0]

    # print("y=",y)
    model.obj.display()

    def pyomo_postprocess( options=None, instance=None, results=None ):
        model.x.display()

    pyomo_postprocess(None, model, results)
    for v in model.component_objects(Var, active=True):
        print("Variable component object", v)
        varobject = getattr(model, str(v))
        for index in varobject:
            if varobject[index].value != 0:
                print("   ", index, varobject[index].value)
    '''
    return df_x, q_data, profit, cost, nonq_data