Exemplo n.º 1
0
import pyomo.environ as pyo

model = pyo.AbstractModel()

# @decl:
model.A = pyo.Set(dimen=2)
model.B = pyo.Param(model.A)
# @:decl

instance = model.create_instance('param5a.dat')

keys = instance.B.keys()
for key in sorted(keys):
    print(str(key) + " " + str(pyo.value(instance.B[key])))
    def build(self):

        r = self.r
        par = self.par
        timerange = self.timerange
        getUbergreifend = self.getUbergreifend

        m = pe.ConcreteModel()
        m.fach = pe.Set(initialize=r.fach_list, ordered=True)
        m.klas = pe.Set(initialize=r.klassen_list, ordered=True)
        m.lehrer = pe.Set(initialize=r.lehrer_list, ordered=True)
        m.zeit = pe.Set(initialize=range(r.n_zeitslots), ordered=True)
        m.x_set = pe.Set(initialize=self.makex(), ordered=True)
        m.x = pe.Var(m.x_set, domain=pe.Binary)

        ############################################
        ###                                      ###
        ###             CONSTRAINTS              ###
        ###                                      ###
        ############################################

        stundenRelaxiert = par.RelaxStunden

        # Vorgaben
        m.vorgaben_set = pe.Set(initialize=r.vorgaben.keys(), ordered=True)
        m.vorgaben = pe.Constraint(m.vorgaben_set * m.zeit, name="vorgaben")
        for k, i in m.vorgaben_set:
            for z in r.vorgaben_zeiten[(k, i)]:
                z = z - 1
                temp = []
                for l in m.lehrer:
                    for f in r.vorgaben[k, i]:
                        for t in timerange(f, z):
                            if (f, k, l, t) in m.x_set:
                                temp.append((f, k, l, t))
                if len(temp) == 0:
                    continue
                m.vorgaben[k, i, z] = sum(m.x[f, k, l, z]
                                          for f, k, l, z in temp) >= 1

        # Vorgaben mit lehrer
        m.vorgaben_set_ml = pe.Set(initialize=r.vorgaben_mit_lehrer.keys(),
                                   ordered=True)
        m.vorgaben_ml = pe.Constraint(m.vorgaben_set_ml * m.zeit)
        for k, l, i in m.vorgaben_set_ml:
            for z in r.vorgaben_ml_zeiten[(k, i)]:
                temp = []
                for f in r.vorgaben[k, i]:
                    for t in timerange(f, z):
                        if (f, k, l, t) in m.x_set:
                            temp.append((f, k, l, t))
                if len(temp) == 0:
                    continue

        # Nur ein Unterricht pro Stunde (außer fuer geteilte Faecher)

        m.maxunterricht = pe.Constraint(m.klas * m.zeit)
        for k, z in m.klas * m.zeit:
            temp = []
            for f in m.fach:
                for l in m.lehrer:
                    for t in timerange(f, z):
                        if (f, k, l, t) in m.x_set and f != "Tandem":
                            temp.append((f, k, l, t))
            if len(temp) == 0:
                continue
            m.maxunterricht[k, z] = sum(
                m.x[f, k, l, z] / r.geteilt[r.fach_dict[f]]
                for f, k, l, z in temp) <= 1

        # Gleichzeitige Faecher
        # Wenn faecher gleicheitig stattfinden, setze die Summen als gleich

        m.gleichzeitig_set = pe.Set(initialize=r.gleichzeitig, ordered=True)
        m.gleichzeitigCtr = pe.Constraint(m.gleichzeitig_set * m.klas * m.zeit)
        for f1, f2, k, z in m.gleichzeitig_set * m.klas * m.zeit:
            temp1 = [(f1, k, l, z) for l in m.lehrer
                     if (f1, k, l, z) in m.x_set]
            temp2 = [(f2, k, l, z) for l in m.lehrer
                     if (f2, k, l, z) in m.x_set]
            if len(temp2) == 0 and len(temp1) == 0:
                continue
            m.gleichzeitigCtr[f1, f2, k, z] = sum(
                m.x[f1, k, l, z]
                for f1, k, l, z in temp1) == sum(m.x[f2, k, l, z]
                                                 for f2, k, l, z in temp2)

        # Gleichzeitige und geteilte Faecher

        temp = [(f, k, z) for f in r.gleichzeitig_geteilt for k in m.klas
                for z in m.zeit if f in r.klassenfach[r.klassen_dict[k]]]
        m.ggf_set = pe.Set(initialize=temp, ordered=True)
        m.ggf = pe.Var(m.ggf_set, domain="Binary")
        m.ggfCtr = pe.Constraint(m.ggf_set)

        for f, k, z in m.ggf_set:
            temp = [(f, k, l, t) for l in lehrer if (f, k, l, t) in m.x_set]
            if len(temp) == 0:
                continue
            m.ggfCtr[f, k, z] = sum(m.x[f, k, l, z] / r.geteilt[r.fach_dict[f]]
                                    for f, k, l, z in temp) == m.ggf[f, k, z]

        # Klassenuebergreifende Faecher (2 in 1)

        temp = []
        for f, i, k in r.ubergreifend:
            if len(k) >= 2:
                for j in range(len(k) - 1):
                    temp.append((f, k[j], k[j + 1]))
        m.kug = pe.Set(initialize=temp, ordered=True)
        m.ubergreifendCtr = pe.Constraint(m.kug * m.lehrer * m.zeit)
        for f, k1, k2, l, z in m.kug * m.lehrer * m.zeit:
            if (f, k1, l, z) in m.x_set:
                if (f, k2, l, z) in m.x_set:
                    m.ubergreifendCtr[f, k1, k2, l,
                                      z] = m.x[f, k1, l, z] == m.x[f, k2, l, z]
                else:
                    m.ubergreifendCtr[f, k1, k2, l, z] = m.x[f, k1, l, z] == 0
            else:
                if (f, k2, l, z) in m.x_set:
                    m.ubergreifendCtr[f, k1, k2, l, z] = m.x[f, k2, l, z] == 0

        # Ein lehrer kann nur einen Unterricht geben
        # (außer fuer klassenuebergreifende Faecher)

        m.lehrerFrei = pe.Constraint(m.lehrer * m.zeit)

        tempUber = set([f for f, i, k in r.ubergreifend])

        for l, z in m.lehrer * m.zeit:
            temp = []
            for f in r.lehrer_faecher[r.lehrer_dict[l]]:
                for k in m.klas:
                    for t in timerange(f, z):
                        if f not in tempUber:
                            temp.append((f, k, t))
            for f, i, k in r.ubergreifend:
                if len(k) >= 0 and f in r.lehrer_faecher[r.lehrer_dict[l]]:
                    for t in timerange(f, z):
                        temp.append((f, k[0], t))

            temp = [(f, k, t) for f, k, t in temp if (f, k, l, t) in m.x_set]
            if temp == []:
                continue

            m.lehrerFrei[l, z] = sum(m.x[f, k, l, t] for f, k, t in temp) <= 1

        # Jeder Klasse muss gewisse UnterrichtStunden machen
        if not stundenRelaxiert:
            m.stundenCtr = pe.Constraint(m.fach * m.klas)
            for f, k in m.fach * m.klas:
                temp = [(f, k, l, z) for l in m.lehrer for z in m.zeit
                        if (f, k, l, z) in m.x_set]
                if len(temp) == 0: continue

                m.stundenCtr[f,
                             k] = sum(m.x[f, k, l, z] * float(self.dauer(f)) /
                                      float(r.geteilt[r.fach_dict[f]])
                                      for f, k, l, z in temp) >= r.stunden[
                                          r.klassen_dict[k]][r.fach_dict[f]]

        # gleichgultige Faecher mussen zusaetzliche Unterrichtstunden machen

        tempgg = []
        for i, k in enumerate(r.klassen_list):
            for ff, d in r.gleichgultig[i]:
                tempgg.append((k, tuple(ff), d))
        m.gleichgultig_set = pe.Set(initialize=range(len(tempgg)),
                                    ordered=True)

        m.gleichgultigCtr = pe.Constraint(m.gleichgultig_set)
        for i, j in enumerate(tempgg):
            k, ff, d = j
            temp = [(f, k, l, z) for f in ff for l in m.lehrer for z in m.zeit
                    if (f, k, l, z) in m.x_set]
            if len(temp) == 0:
                continue
            m.gleichgultigCtr[i] = sum(
                m.x[f, k, l, z] * float(self.dauer(f)) /
                float(r.geteilt[r.fach_dict[f]])
                for f, k, l, z in temp) >= d + sum(
                    r.stunden[r.klassen_dict[k]][r.fach_dict[f]] for f in ff)

        # Tandemlehrer wird gebraucht

        m.tandemCtr = pe.Constraint(m.klas, m.zeit)
        for k, z in m.klas * m.zeit:
            temp1, temp2 = [], []
            for l in m.lehrer:
                if ("Tandem", k, l, z) in m.x_set:
                    temp2.append(("Tandem", k, l, z))
                for f in m.fach:
                    for t in timerange(f, z):
                        if (f, k, l, t) in m.x_set:
                            temp1.append((f, k, l, t))

            if len(temp1) + len(temp2) == 0:
                continue
            m.tandemCtr[k,
                        z] = sum(m.x[f, k, l, t] * r.tandem[r.fach_dict[f]]
                                 for f, k, l, t in temp1) == sum(
                                     m.x[f, k, l, z] for f, k, l, z in temp2)

        # Lehrer sollten nicht Ihren Arbeitzeit ueberschreiten

        m.maxArbeitCtr = pe.Constraint(m.lehrer)
        for l in m.lehrer:
            temp = [(f, k, l, z) for f, k, z in m.fach * m.klas * m.zeit
                    if (f, k, l, z) in m.x_set]
            if temp == []:
                continue
            m.maxArbeitCtr[l] = sum(
                m.x[f, k, l, z] * self.dauer(f) / getUbergreifend(f, k)
                for f, k, l, z in temp) <= r.arbeitzeit[r.lehrer_dict[l]]

        # Raum Verfuegbarkeit

        m.raume = pe.Set(initialize=range(len(r.raum_faecher)), ordered=True)
        m.raumCtr = pe.Constraint(m.raume * m.zeit)
        for raum, z in m.raume * m.zeit:
            if r.raum_verfugbar[raum][z] < 1:
                continue
            temp = []
            for f in r.raum_faecher[raum]:
                for k, l in m.klas * m.lehrer:
                    for t in timerange(f, z):
                        if (f, k, l, t) in m.x_set:
                            temp.append((f, k, l, t))
            if len(temp) == 0:
                continue
            m.raumCtr[raum, z] = sum(
                m.x[f, k, l, t] / getUbergreifend(f, k)
                for f, k, l, t in temp) <= r.raum_verfugbar[raum][z]

        ############################################
        ###                                      ###
        ###           SOFT CONSTRAINTS           ###
        ###                                      ###
        ############################################

        # Relaxation: jeder Klasse muss gewisse UnterrichtStunden machen
        if stundenRelaxiert:
            m.stundenRel = pe.Var(m.fach * m.klas, domain=pe.NonNegativeReals)
            m.stundenCtr = pe.Constraint(m.fach * m.klas)
            for f, k in m.fach * m.klas:
                temp = [(f, k, l, z) for l in m.lehrer for z in m.zeit
                        if (f, k, l, z) in m.x_set]
                if len(temp) == 0: continue

                m.stundenCtr[f, k] = sum(
                    m.x[f, k, l, z] * float(self.dauer(f)) /
                    float(r.geteilt[r.fach_dict[f]])
                    for f, k, l, z in temp) + m.stundenRel[f, k] >= r.stunden[
                        r.klassen_dict[k]][r.fach_dict[f]]

        # Lehrer Wechsel Variable
        m.wrange = pe.Set(
            initialize=[i for i in m.zeit if not i + 1 in r.tag_anfang],
            ordered=True)
        m.lw = pe.Var(m.klas * m.wrange, domain=pe.NonNegativeReals)
        m.lwCtr = pe.Constraint(m.klas * m.wrange * m.lehrer)
        for k, z, l in m.klas * m.wrange * m.lehrer:
            temp1 = [(f, t) for f in m.fach for t in timerange(f, z)
                     if (f, k, l, t) in m.x_set]
            temp2 = [(f, t) for f in m.fach for t in timerange(f, z - 1)
                     if (f, k, l, t) in m.x_set]
            if len(temp1) + len(temp2) == 0:
                continue
            m.lwCtr[k, z, l] = m.lw[k, z] >= sum(
                m.x[f, k, l, t] for f, t in temp1) - sum(m.x[f, k, l, t]
                                                         for f, t in temp2)

        # Sport zusammen

        m.sportZusammen = pe.Var(m.klas * m.zeit, domain=pe.Binary)
        m.sportZusammenCtr = pe.Constraint(m.klas * m.zeit)
        for k, z in m.klas * m.zeit:
            temp1 = [l for l in m.lehrer if ("SportW", k, l, z) in m.x_set]
            temp2 = [l for l in m.lehrer if ("SportM", k, l, z) in m.x_set]
            m.sportZusammenCtr[k, z] = m.sportZusammen[
                k, z] <= (sum(m.x["SportW", k, l, z]
                              for l in temp1) + sum(m.x["SportM", k, l, z]
                                                    for l in temp2)) / 2.0

        # Minimiere den Anzahl von Lehrer pro Klasse
        m.lehrerInKlasse = pe.Var(m.klas * m.lehrer, domain=pe.Binary)
        m.lehrerInKlasseCtr = pe.Constraint(m.klas * m.lehrer)

        for k, l in m.klas * m.lehrer:
            m.lehrerInKlasseCtr[k, l] = m.lehrerInKlasse[k, l] >= sum(
                m.x[f, k, l, z] for f in r.lehrer_faecher[r.lehrer_dict[l]]
                for z in m.zeit if
                (f, k, l, z) in m.x_set) / (r.arbeitzeit[r.lehrer_dict[l]] + 1)

        ############################################
        ###                                      ###
        ### OBJECTIVE FUNCTION AND MAXIMIZATION  ###
        ###                                      ###
        ############################################

        def objRule(m):
            res = 0

            # Lehrer Wechsel Variable
            res += -par.WechselGewicht * sum(m.lw[k, z]
                                             for k, z in m.klas * m.wrange)
            # Sport zusammen
            res += par.SportGewicht * sum(m.sportZusammen[k, z]
                                          for k, z in m.klas * m.zeit)
            # Minimiere den Anzahl von Lehrer pro Klasse
            res += par.LehrerAnzahlStrafe * sum(m.lehrerInKlasse[k, l]
                                                for k, l in m.klas * m.lehrer)

            # Hauptehrer unterrichtet am meisten in seiner eigenen Klasse.
            res += par.KlassenLehrerGewicht * sum(m.x[f, k, l, z]
                                                  for f, k, l, z in m.x_set
                                                  if l == r.klassen_lehrer[k])
            # Tandemlehrer unterrichtet am meisten in seiner eigenen Klasse.
            res += par.TandemLehrerGewicht * sum(m.x[f, k, l, z]
                                                 for f, k, l, z in m.x_set
                                                 if l == r.klassen_tandem[k])
            # Partnerlehrer unterrichtet am meisten in seiner eigenen Klasse.
            res += par.PartnerLehrerGewicht * sum(m.x[f, k, l, z]
                                                  for f, k, l, z in m.x_set
                                                  if l in r.klassen_partner[k])

            if stundenRelaxiert:
                res -= par.GrosseStrafe * sum(m.stundenRel[f, k]
                                              for f, k in m.fach * m.klas)

            return -res

        m.obj = pe.Objective(rule=objRule)

        self.m = m
def reboiler_stage_rule(block):
    #-----------------------------------SETS-----------------------------------

    # local sets that will only be used in reactive stage
    block.inlet = pe.Set(initialize=['in'])
    block.outlet = pe.Set(initialize=['out', 'P'])
    block.stream = block.inlet | block.outlet

    #---------------------------------VARIABLES---------------------------------

    block.T_F = pe.Var(within=pe.NonNegativeReals)  # K
    block.P = pe.Var(within=pe.NonNegativeReals, bounds=(10, 30))  # Bar
    block.Q_main = pe.Var(within=pe.Reals)  # MW
    # Tray Inlet/Outlet Variable
    block.x_ = pe.Var(block.inlet,
                      m.COMP_TOTAL,
                      within=pe.NonNegativeReals,
                      bounds=(0, 1))
    block.y_ = pe.Var(block.inlet,
                      m.COMP_TOTAL,
                      within=pe.NonNegativeReals,
                      bounds=(0, 1))
    block.x = pe.Var(m.COMP_TOTAL, within=pe.NonNegativeReals, bounds=(0, 1))
    block.y = pe.Var(m.COMP_TOTAL, within=pe.NonNegativeReals, bounds=(0, 1))
    block.z = pe.Var(m.COMP_FEED, within=pe.NonNegativeReals, bounds=(0, 1))

    block.L = pe.Var(block.stream, within=pe.NonNegativeReals)
    block.V = pe.Var(block.stream, within=pe.NonNegativeReals)
    block.F = pe.Var(within=pe.NonNegativeReals)

    block.H_L_ = pe.Var(block.inlet, within=pe.Reals)
    block.H_V_ = pe.Var(block.inlet, within=pe.Reals)
    block.H_L = pe.Var(within=pe.Reals)
    block.H_V = pe.Var(within=pe.Reals)

    block.T = pe.Var(within=pe.NonNegativeReals,
                     bounds=(200 + 273.15, 350 + 273.15))  # K
    block.H_F = pe.Var(within=pe.Reals)
    block.f_V = pe.Var(m.COMP_TOTAL, within=pe.PositiveReals, initialize=1e-20)
    block.f_L = pe.Var(m.COMP_TOTAL, within=pe.PositiveReals, initialize=1e-20)

    print('>', 'Importing Non Reactive Stage......')
    print('>', 'Adding the following local variable:')
    print('-' * 36)

    for i in block.component_objects(pe.Var, active=True):
        print('|', i)

    print('-' * 36)
    print('')
    #---------------------------------Equations---------------------------------
    #with HiddenPrints():

    # Energy Block
    block.energy_block = pe.Block(rule=energy_block_rule)

    # VLE block
    block.VLE_block = pe.Block(rule=VLE_block_rule)

    # Mass Balance
    def mass_balance_main_rule(block, i):
        if i in m.COMP_FEED:
            return block.F*block.z[i] + sum(block.L[s]*block.x_[s,i] + block.V[s]*block.y_[s,i] for s in block.inlet)\
             - sum(block.L[s]*block.x[i] + block.V[s]*block.y[i] for s in block.outlet) == 0
        else:
            return sum(block.L[s]*block.x_[s,i] + block.V[s]*block.y_[s,i] for s in block.inlet)\
             - sum(block.L[s]*block.x[i] + block.V[s]*block.y[i] for s in block.outlet) == 0

    block.mass_balance_main_con = pe.Constraint(m.COMP_TOTAL,
                                                rule=mass_balance_main_rule)

    # Equilibrium
    def VL_equil_rule(block, i):
        return block.f_V[i] == block.f_L[i]

    block.VL_equil_con = pe.Constraint(m.COMP_TOTAL, rule=VL_equil_rule)

    # MPCC formation
    block.MPCC_P_pf = pe.Block(rule=P_pf_block_rule)
    block.MPCC_P_NCP = pe.Block(rule=P_NCP_block_rule)
    block.MPCC_P_Reg = pe.Block(rule=P_Reg_block_rule)

    # by default deactivated, can be switched after the block is constructed
    select_MPCC(block, 'pf')

    # Summation
    def summation_x_y_rule(block):
        return sum(block.x[i]
                   for i in m.COMP_TOTAL) == sum(block.y[i]
                                                 for i in m.COMP_TOTAL)

    block.summation_x_y_con = pe.Constraint(rule=summation_x_y_rule)

    def summation_total_mass_rule(block):
        return block.F + sum(block.L[s] + block.V[s] for s in block.inlet) \
                - sum(block.L[s] + block.V[s] for s in block.outlet) == 0

    block.summation_total_mass_con = pe.Constraint(
        rule=summation_total_mass_rule)

    # Heat Balance
    def heat_balance_main_rule(block):
        return block.F*block.H_F + sum(block.L[s]*block.H_L_[s] + block.V[s]*block.H_V_[s] for s in block.inlet) \
                + block.Q_main - sum(block.L[s]*block.H_L + block.V[s]*block.H_V for s in block.outlet) == 0

    block.heat_balance_main_con = pe.Constraint(rule=heat_balance_main_rule)
Exemplo n.º 4
0
###NOTE: as of May 16, this will not even come close to running. DLW
### and it is "wrong" in a lot of places.
### Someone should edit this file, then delete these comment lines. DLW may 16
"""
David L. Woodruff and Mingye Yang, Spring 2018
Code snippets for scripts.rst in testable form
"""
import pyomo.environ as pyo

instance = pyo.ConcreteModel()
instance.I = pyo.Set(initialize=[1, 2, 3])
instance.sigma = pyo.Param(mutable=True, initialize=2.3)
instance.Theta = pyo.Param(instance.I, mutable=True)
for i in instance.I:
    instance.Theta[i] = i
ParamName = "Theta"
idx = 1
NewVal = 1134

# @Assign_value_to_indexed_parametername
instance.ParamName[idx].value = NewVal
# @Assign_value_to_indexed_parametername

ParamName = "sigma"

# @Assign_value_to_unindexed_parametername_2
instance.ParamName.value = NewVal
# @Assign_value_to_unindexed_parametername_2

instance.x = pyo.Var([1, 2, 3], initialize=0)
instance.y = pyo.Var()
Exemplo n.º 5
0
def _aggregate_planning(linear=False, **kwargs):
    """
    Factory method returning Pyomo Abstract/Concrete Model
    for the Aggregate Planning Problem

    Parameters
    ----------
    **kwargs
        Passed into Pyomo Abstract Model's `create_instance`
        to return Pyomo Concrete Model instead.

    Notes
    -----
    """
    def _obj_expression(model):
        """Objective Expression: """
        return (pyo.summation(model.Cost, model.Produce) +
                model.HoldingCost * pyo.summation(model.InvLevel))

    def _conserve_flow_constraint_rule(model, p):
        """Constraints for """
        ind = model.Periods.ord(p)
        if ind == 1:
            return (model.InitialInv + model.Produce[p] -
                    model.InvLevel[p] == model.Demand[p])
        else:
            last_p = model.Periods[ind - 1]
            return (model.InvLevel[last_p] + model.Produce[p] -
                    model.InvLevel[p] == model.Demand[p])

    def _max_storage_constraint_rule(model, p):
        return (0, model.InvLevel[p], model.MaxStorage)

    def _final_inv_constraint_rule(model):
        last_period = model.Periods[-1]
        return model.InvLevel[last_period] == model.FinalInv

    # Create the abstract model & dual suffix
    model = pyo.AbstractModel()
    model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
    # Define sets/params that are always used
    model.Periods = pyo.Set(ordered=True)
    model.Cost = pyo.Param(model.Periods)
    model.Demand = pyo.Param(model.Periods)
    model.HoldingCost = pyo.Param()
    model.MaxStorage = pyo.Param(within=pyo.Any, default=None)
    model.InitialInv = pyo.Param(default=0)
    model.FinalInv = pyo.Param(default=0)
    # Define decision variables
    model.Produce = pyo.Var(
        model.Periods,
        within=pyo.NonNegativeReals if linear else pyo.NonNegativeIntegers)
    model.InvLevel = pyo.Var(
        model.Periods,
        within=pyo.NonNegativeReals if linear else pyo.NonNegativeIntegers)
    # Define objective & constraints
    model.OBJ = pyo.Objective(rule=_obj_expression, sense=pyo.minimize)
    model.ConserveFlowConstraint = pyo.Constraint(
        model.Periods, rule=_conserve_flow_constraint_rule)
    model.MaxStorageConstraint = pyo.Constraint(
        model.Periods, rule=_max_storage_constraint_rule)
    model.FinalInvConstraint = pyo.Constraint(rule=_final_inv_constraint_rule)
    # Check if returning concrete or abstract model
    if kwargs:
        return model.create_instance(**kwargs)
    else:
        return model
Exemplo n.º 6
0
# a file hosts all global referred parameters/sets/etcself.
from pyomo import environ as pe
from data.thermal_data import Tb
from utility.data_utility import cal_cnumber

m = pe.ConcreteModel()

m.COMP_OLEFIN = pe.Set(initialize=['C{0}H{1}'.format(i,2*i) for i in range(2,21)],ordered=True)
m.COMP_PARAFFIN = pe.Set(initialize=['C{0}H{1}'.format(i,2*i+2) for i in range(1,57)],ordered=True)
m.COMP_INORG = pe.Set(initialize=['H2','CO','CO2','H2O'],ordered=True)
m.COMP_ORG = m.COMP_OLEFIN | m.COMP_PARAFFIN
m.COMP_TOTAL = m.COMP_INORG | m.COMP_OLEFIN | m.COMP_PARAFFIN

m.COMP_FEED = pe.Set(initialize=['H2','CO','C30H62'],ordered=True)
# m.COMP_FEED = m.COMP_INORG | m.COMP_OLEFIN | m.COMP_PARAFFIN

'''
Sort components based on boiling point
'''
product_boiling_C = [(i,Tb[i]) for i in m.COMP_ORG]
def pick_comp(x):
    return x[1]
m.COMP_SORTED_BP = pe.Set(initialize=[i for i,T in sorted(product_boiling_C,key =pick_comp )],ordered=True)

'''
Product definition
'''
m.PRODUCT = pe.Set(initialize=['naphtha','gasoline','diesel','heavy','intermediate'],ordered=True)
m.PRODUCT_cnumber = pe.Set(m.PRODUCT)
m.PRODUCT_cnumber['naphtha'] = [i for i in m.COMP_ORG if cal_cnumber(i) >= 5 and cal_cnumber(i) <= 7]
m.PRODUCT_cnumber['gasoline'] = [i for i in m.COMP_ORG if cal_cnumber(i) >= 8 and cal_cnumber(i) <= 12]
Exemplo n.º 7
0
    def createInterdictionDual(self):
        # Create the model
        model = pe.ConcreteModel()

        # Add the sets
        model.node_set = pe.Set(initialize=self.node_set)
        model.edge_set = pe.Set(initialize=self.arc_set, dimen=2)
        model.commodity_set = pe.Set(initialize=self.commodity_set)

        # Create the variables
        model.rho = pe.Var(model.node_set * model.commodity_set,
                           domain=pe.Reals)
        model.piSingle = pe.Var(model.edge_set * model.commodity_set,
                                domain=pe.NonPositiveReals)
        model.piJoint = pe.Var(model.edge_set, domain=pe.NonPositiveReals)

        model.x = pe.Var(model.edge_set, domain=pe.Binary)

        # Create the objective
        def obj_rule(model):
            return  sum(data['Capacity']*model.piJoint[e] for e,data in self.arc_data.iterrows() if data['Capacity']>=0) +\
                    sum(data['Capacity']*model.piSingle[e] for e,data in self.arc_commodity_data.iterrows() if data['Capacity']>=0)+\
                    sum(data['SupplyDemand']*model.rho[n] for n,data in self.node_commodity_data.iterrows())

        model.OBJ = pe.Objective(rule=obj_rule, sense=pe.maximize)

        # Create the constraints for y_ijk
        def edge_constraint_rule(model, i, j, k):
            if (i, j, k) not in self.arc_commodity_data.index:
                return pe.Constraint.Skip
            attackable = int(self.arc_data['Attackable'].get((i, j), 0))
            hasSingleCap = int(
                self.arc_commodity_data['Capacity'].get((i, j, k), -1) >= 0)
            hasJointCap = int(self.arc_data['Capacity'].get((i, j), -1) >= 0)
            return model.rho[(j, k)] - model.rho[(i, k)] + model.piSingle[
                (i, j, k)] * hasSingleCap + model.piJoint[
                    (i,
                     j)] * hasJointCap <= self.arc_commodity_data['Cost'].get(
                         (i, j, k)) + (2 * self.nCmax + 1) * model.x[
                             (i, j)] * attackable

        model.DualEdgeConstraint = pe.Constraint(model.edge_set *
                                                 model.commodity_set,
                                                 rule=edge_constraint_rule)

        # Create constraints for the UnsatDemand variables
        def unsat_constraint_rule(model, n, k):
            if (n, k) not in self.node_commodity_data.index:
                return pe.Constraint.Skip
            imbalance = self.node_commodity_data['SupplyDemand'].get((n, k), 0)
            supply_node = int(imbalance < 0)
            demand_node = int(imbalance > 0)
            if (supply_node):
                return -model.rho[(n, k)] <= self.nCmax
            if (demand_node):
                return model.rho[(n, k)] <= self.nCmax
            return pe.Constraint.Skip

        model.UnsatConstraint = pe.Constraint(model.node_set *
                                              model.commodity_set,
                                              rule=unsat_constraint_rule)

        # Create the interdiction budget constraint
        def block_limit_rule(model):
            model.attacks = self.attacks
            return pe.summation(model.x) <= model.attacks

        model.BlockLimit = pe.Constraint(rule=block_limit_rule)

        # Create, save the model
        self.Idual = model
def condenser_stage_rule(block):
    #-----------------------------------SETS-----------------------------------

    # local sets that will only be used in reactive stage
    block.inlet = pe.Set(initialize=['in'])
    block.outlet = pe.Set(initialize=['out','P'])
    block.stream = block.inlet | block.outlet
    block.COMP_WATER = pe.Set(initialize=['H2O'])

    #---------------------------------VARIABLES---------------------------------

    block.T = pe.Var(within=pe.NonNegativeReals,bounds=(20+273.15,40+273.15)) # K
    block.T_F = pe.Var(within=pe.NonNegativeReals) # K
    block.P = pe.Var(within=pe.NonNegativeReals,bounds=(10,30)) # Bar
    block.Q_main = pe.Var(within=pe.Reals) # MW
    # Tray Inlet/Outlet Variable
    block.x_ = pe.Var(block.inlet,m.COMP_TOTAL,within=pe.NonNegativeReals,bounds=(0,1))
    block.y_ = pe.Var(block.inlet,m.COMP_TOTAL,within=pe.NonNegativeReals,bounds=(0,1))
    block.x = pe.Var(m.COMP_TOTAL,within=pe.NonNegativeReals,bounds=(0,1))
    block.y = pe.Var(m.COMP_TOTAL,within=pe.NonNegativeReals,bounds=(0,1))
    block.z = pe.Var(m.COMP_FEED,within=pe.NonNegativeReals,bounds=(0,1))

    block.L = pe.Var(block.stream,within=pe.NonNegativeReals)
    block.W = pe.Var(within=pe.NonNegativeReals)
    block.V = pe.Var(block.stream,within=pe.NonNegativeReals)
    block.F = pe.Var(within=pe.NonNegativeReals)

    block.H_L_ = pe.Var(block.inlet,within=pe.Reals)
    block.H_V_ = pe.Var(block.inlet,within=pe.Reals)
    block.H_L = pe.Var(within=pe.Reals)
    block.H_V = pe.Var(within=pe.Reals)

    block.H_F = pe.Var(within=pe.Reals)
    block.f_V = pe.Var(m.COMP_TOTAL,within=pe.NonNegativeReals,initialize=1e-20)
    block.f_L = pe.Var(m.COMP_TOTAL,within=pe.NonNegativeReals,initialize=1e-20)

    block.PR_L = pe.Var(within=pe.NonNegativeReals,bounds=(0,1))

    print('|','Importing Condenser Stage......')
    print('|','Adding the following local variable:')
    print('-'*36)

    for i in block.component_objects(pe.Var,active=True):
        print('|',i)

    print('-'*36)
    print('')

    #---------------------------------Equations---------------------------------

    # Energy Block
    block.energy_block = pe.Block(rule=energy_block_rule)

    # VLE block
    block.VLE_block = pe.Block(rule=VLLE_block_rule)

    # Mass Balance
    def mass_balance_main_rule(block,i):
        if i in m.COMP_FEED:
            return block.F*block.z[i] + sum(block.L[s]*block.x_[s,i] + block.V[s]*block.y_[s,i] for s in block.inlet)\
            - sum(block.L[s]*block.x[i] + block.V[s]*block.y[i] for s in block.outlet) == 0
        elif i in block.COMP_WATER:
            return sum(block.L[s]*block.x_[s,i] + block.V[s]*block.y_[s,i] for s in block.inlet)\
            - sum(block.L[s]*block.x[i] + block.V[s]*block.y[i] for s in block.outlet) - block.W == 0
        else:
            return sum(block.L[s]*block.x_[s,i] + block.V[s]*block.y_[s,i] for s in block.inlet)\
            - sum(block.L[s]*block.x[i] + block.V[s]*block.y[i] for s in block.outlet) == 0
    block.mass_balance_main_con = pe.Constraint(m.COMP_TOTAL,rule=mass_balance_main_rule)

    # Equilibrium
    def VL_equil_rule(block,i):
        return block.f_V[i] == block.f_L[i]
    block.VL_equil_con = pe.Constraint(m.COMP_TOTAL-block.COMP_WATER,rule=VL_equil_rule)

    # Water phase
    def L_water_rule(block,i):
        return block.x[i] == pe.exp(-0.66037 - 7.1130*(539.1/block.T) - 0.67885*(1-block.T/539.1)**(1/3) -1.43381*(1-block.T/539.1))
    block.L_water_con = pe.Constraint(block.COMP_WATER,rule=L_water_rule)

    def V_water_rule(block,i):
        return block.y[i]*block.P == pe.exp(2.30258509299*(5.20389 - 1733.926/(block.T-39.485)))
    block.V_water_con = pe.Constraint(block.COMP_WATER,rule=V_water_rule)

    # add bounds specifically for water
    block.x['H2O'].setub(water_x[1]+abs(water_x[1])*0.1)
    block.x['H2O'].setlb(water_x[0]-abs(water_x[0])*0.1)

    block.y['H2O'].setub(water_yp[1]/block.P.lb)
    block.y['H2O'].setlb(water_yp[0]/block.P.ub)

    # Summation
    def summation_x_main_rule(block):
        return sum(block.x[i] for i in m.COMP_TOTAL) == 1
    block.summation_x_main_con = pe.Constraint(rule=summation_x_main_rule)

    def summation_y_main_rule(block):
        return sum(block.y[i] for i in m.COMP_TOTAL) == 1
    block.summation_y_main_con = pe.Constraint(rule=summation_y_main_rule)

    # Heat Balance
    def heat_balance_main_rule(block):
        return block.F*block.H_F + sum(block.L[s]*block.H_L_[s] + block.V[s]*block.H_V_[s] for s in block.inlet) \
                + block.Q_main - sum(block.L[s]*block.H_L + block.V[s]*block.H_V for s in block.outlet) \
                - block.W*block.energy_block.dH_L['H2O'] == 0
    block.heat_balance_main_con = pe.Constraint(rule=heat_balance_main_rule)

    # product / out ratio
    def PR_L_ratio_rule(block):
        return block.L['P'] == block.PR_L * sum(block.L[s] for s in block.outlet)
    block.PR_L_con = pe.Constraint(rule=PR_L_ratio_rule)
Exemplo n.º 9
0
pyutilib.subprocess.GlobalData.DEFINE_SIGNAL_HANDLERS_DEFAULT = False

import pyomo.environ as pyo
import numpy as np
import matplotlib.pyplot as plt
from pyomo.opt import SolverFactory
import os
import sys

##Declare model (to be used)
#concrete or abstract models are two different pyomo models
m = pyo.ConcreteModel()

##SET
#SET I = all Units
m.I = pyo.Set(initialize = ['ICE','Boiler1','Boiler2','HP'])
#now let's define the subsets.
#We can have electricity consuming devices or fuel consuming devices as the inlet and electricity or heat as the output.
#Our subsets are defined within the main set I, which we indicate by the command within.
m.I_f = pyo.Set(within = m.I, initialize = ['ICE','Boiler1','Boiler2'])
m.I_el = pyo.Set(within = m.I, initialize = ['ICE'])
m.I_th = pyo.Set(within = m.I, initialize = ['ICE','Boiler1','Boiler2','HP'])
#this is heat pump which consumes electricity
m.I_el_consum = pyo.Set(within = m.I, initialize = ['HP'])
#We don't have organic rankine cycle; if we had, we could define a set for later setting the constraint of maximum startups.
#m.I_ORC = pyo.Set(within = m.I, initialize = ['ORC'])

#SET T = all time instants (24 hs in a day)
T = 24 #elemnts in the Set
m.T= pyo.RangeSet(0,T-1)
Exemplo n.º 10
0
def DC_OPF_RO_TruthTable(Elecdata, TruthTable):

    Gen = Elecdata.Gen
    Branch = Elecdata.Branch
    Bus = Elecdata.Bus

    GasGenerators = Gen[Gen.FuelType == 'Gas'].index.tolist()

    nscen = len(TruthTable)

    m = pm.ConcreteModel()

    m.gen_set = pm.Set(initialize=Gen.index.tolist())
    m.branch_set = pm.Set(initialize=Branch.index.tolist())
    m.bus_set = pm.Set(initialize=Bus.index.tolist())

    m.scen_set = pm.RangeSet(0, nscen - 1)
    m.gasgen_set = pm.Set(initialize=GasGenerators,
                          within=m.gen_set,
                          ordered=True)

    m.P_UB = pm.Var(m.gasgen_set,
                    bounds=lambda m, i: (Gen.DC_OPF_RES[i], Gen.Pmax_MW[i]),
                    initialize=lambda m, i: Gen.DC_OPF_RES[i])
    m.P_LB = pm.Var(m.gasgen_set,
                    bounds=lambda m, i: (Gen.Pmin_MW[i], Gen.DC_OPF_RES[i]),
                    initialize=lambda m, i: Gen.DC_OPF_RES[i])
    m.P = pm.Var(m.gen_set,
                 m.scen_set,
                 bounds=lambda m, i, s: (Gen.Pmin_MW[i], Gen.Pmax_MW[i]),
                 initialize=1)
    m.Pij = pm.Var(m.branch_set,
                   m.scen_set,
                   bounds=lambda m, i, s:
                   (-Branch.RateA_MVA[i], Branch.RateA_MVA[i]),
                   initialize=1)
    m.th = pm.Var(m.bus_set, m.scen_set, bounds=(-np.pi, np.pi), initialize=0)
    m.P_Shed = pm.Var(m.gasgen_set, bounds=(0, None))
    m.P_Add = pm.Var(m.gasgen_set, bounds=(0, None))

    def PowerBal_constr(model, i, s):
        PowerBal = -Bus.PD_MW[i] \
        + sum(m.P[k,s]   for k in Gen[Gen.Gen_Bus==i].index.tolist()) \
        - sum(m.Pij[k,s] for k in Branch[Branch.From_Bus==i].index.tolist()) \
        + sum(m.Pij[k,s] for k in Branch[Branch.To_Bus==i].index.tolist()) \
        ==0
        return PowerBal

    m.PowerBal_constr = pm.Constraint(m.bus_set,
                                      m.scen_set,
                                      rule=PowerBal_constr)

    def Branch_Flow(model, i, s):
        From_ix = Branch.From_Bus[i]
        To_ix = Branch.To_Bus[i]
        B = Elecdata.Params.BaseMVA / Branch.BR_X_PU[i]
        return m.Pij[i, s] == (B) * (m.th[From_ix, s] - m.th[To_ix, s])

    m.branchflow = pm.Constraint(m.branch_set, m.scen_set, rule=Branch_Flow)

    def SlackNode(model, i, s):
        if Bus.Bus_Type[i] == 3:
            return m.th[i, s] == 0
        else:
            return pm.Constraint.Skip

    m.slack = pm.Constraint(m.bus_set, m.scen_set, rule=SlackNode)

    def Power_UB_LB(model, i, s):
        Binary_LB = TruthTable[i][s]  # Truth table index
        Binary_UB = 1 - Binary_LB
        return m.P[i, s] == Binary_UB * m.P_UB[i] + Binary_LB * m.P_LB[i]

    m.Power_UB_LB = pm.Constraint(m.gasgen_set, m.scen_set, rule=Power_UB_LB)

    def Costs(model, s):
        return sum(Gen.CostCoeff_1[k] * m.P[k, s]
                   for k in m.gen_set) <= Elecdata.Params.C_max_RO

    m.Costs = pm.Constraint(m.scen_set, rule=Costs)

    def Shed(model, i):
        return m.P_Shed[i] == Gen.DC_OPF_RES[i] - m.P_LB[i]

    m.shed = pm.Constraint(m.gasgen_set, rule=Shed)

    def Add(model, i):
        return m.P_Add[i] == m.P_UB[i] - Gen.DC_OPF_RES[i]

    m.add = pm.Constraint(m.gasgen_set, rule=Add)

    def DC_OPF_Obj(model):
        return sum(Gen.AddWeight[i] * m.P_Add[i] +
                   Gen.ShedWeight[i] * m.P_Shed[i] for i in m.gasgen_set)

    m.objective = pm.Objective(rule=DC_OPF_Obj,
                               sense=pm.maximize,
                               doc='Define objective function')

    opt = pm.SolverFactory('ipopt')
    opt.options['print_level'] = 5

    # Optimize
    print('Starting Optimization')
    results = opt.solve(m, tee=True)

    status = 0
    if (results.solver.status
            == SolverStatus.ok) and (results.solver.termination_condition
                                     == TerminationCondition.optimal):
        print('Model Solved to Optimality')
        status = 1
    # Do something when the solution in optimal and feasible
    elif (results.solver.termination_condition ==
          TerminationCondition.infeasible):
        print('Model is infeasible')
    # Do something when model in infeasible
    else:
        print('Solver Status: ', results.solver.status)

    UB_Res = dict([[i, np.round(m.P_UB[i].value, decimals=8)] for i in m.P_UB])
    LB_Res = dict([[i, np.round(m.P_LB[i].value, decimals=8)] for i in m.P_LB])

    P_Shed = dict([[i, np.round(m.P_Shed[i].value, decimals=8)]
                   for i in m.P_Shed])
    P_Add = dict([[i, np.round(m.P_Add[i].value, decimals=8)]
                  for i in m.P_Add])

    Elecdata.Gen = Elecdata.Gen.assign(DC_RO_OPF_P_UB=pd.Series(UB_Res))
    Elecdata.Gen = Elecdata.Gen.assign(DC_RO_OPF_P_LB=pd.Series(LB_Res))

    Elecdata.Gen = Elecdata.Gen.assign(P_Shed=pd.Series(P_Shed))
    Elecdata.Gen = Elecdata.Gen.assign(P_Add=pd.Series(P_Add))
    #Elecdata.Gen    =  Elecdata.Gen.combine(pd.DataFrame.from_dict(LB_Res,orient='index',columns=['DC_RO_OPF_P_LB']))

    # Unload results

    Pc = pd.DataFrame(columns=[Gen.index.tolist() + ['Cost', 'Max Cost']],
                      index=TruthTable.index.tolist())
    for s in m.scen_set:
        for g in m.gen_set:
            Pc.loc[s][g] = m.P[g, s].value
        Pc.loc[s]['Cost'] = m.Costs[s].body()
        Pc.loc[s]['Max Cost'] = m.Costs[s].upper()

    Pc.index = ['Case' + str(x) for x in range(0, len(Pc))]

    Pc = Pc.astype(float).round(decimals=1)

    Elecdata.Params.Cases = Pc
    Elecdata.Params.RO_OPF_Obj = m.objective()

    Elecdata.Params.status = status
Exemplo n.º 11
0
def build_time_block(t0: int, delta_t: int, num_finite_elements: int,
                     constant_control_duration: int,
                     time_scale: float) -> _BlockData:
    """
    Parameters
    ----------
    t0: int
        start time
    delta_t: float
        end time
    num_finite_elements:
        number of finite elements
    constant_control_duration:
        number of finite elements over which the control (p) is constant
    time_scale: float
        coefficient of t within the sin function

    Returns
    -------
    m: _BlockData
        The Pyomo model
    """
    assert constant_control_duration >= delta_t
    assert constant_control_duration % delta_t == 0
    assert (num_finite_elements * delta_t) % constant_control_duration == 0

    def finite_element_ndx_to_start_t_x(ndx):
        return t0 + ndx * delta_t

    def finite_element_ndx_to_end_t_x(ndx):
        return t0 + (ndx + 1) * delta_t

    def finite_element_ndx_to_start_t_p(ndx):
        return t0 + (math.floor(
            ndx /
            (constant_control_duration / delta_t))) * constant_control_duration

    m = pe.Block(concrete=True)
    m.x_time_points = pe.Set(initialize=[
        t for t in range(t0, t0 + delta_t * (num_finite_elements + 1), delta_t)
    ])
    m.x = pe.Var(m.x_time_points)
    num_p_elements = int(
        (num_finite_elements * delta_t) / constant_control_duration)
    m.p_time_points = pe.Set(initialize=[
        t for t in range(t0, t0 + constant_control_duration *
                         num_p_elements, constant_control_duration)
    ])
    bnds = (None, 2)
    m.p = pe.Var(m.p_time_points, bounds=bnds)

    obj_expr = 0
    for fe_ndx in range(num_finite_elements):
        start_t_x = finite_element_ndx_to_start_t_x(fe_ndx)
        end_t_x = finite_element_ndx_to_end_t_x(fe_ndx)
        obj_expr += 0.5 * delta_t * (
            (m.x[start_t_x] - (math.sin(time_scale * start_t_x) + 1))**2 +
            (m.x[end_t_x] - (math.sin(time_scale * end_t_x) + 1))**2)
    m.obj = pe.Objective(expr=obj_expr)

    m.con_indices = pe.Set(initialize=[t for t in m.x_time_points if t > t0])
    m.cons = pe.Constraint(m.con_indices)
    for fe_ndx in range(num_finite_elements):
        start_t_x = finite_element_ndx_to_start_t_x(fe_ndx)
        end_t_x = finite_element_ndx_to_end_t_x(fe_ndx)
        start_t_p = finite_element_ndx_to_start_t_p(fe_ndx)
        m.cons[end_t_x] = m.x[end_t_x] - (m.x[start_t_x] + delta_t *
                                          (m.p[start_t_p] - m.x[end_t_x])) == 0

    return m
Exemplo n.º 12
0
def DC_OPF_RO_TruthTable_ConstraintCheck(Elecdata, Cur_TruthTable):

    Gen = Elecdata.Gen
    Branch = Elecdata.Branch
    Bus = Elecdata.Bus
    GasGenerators = Gen[Gen.FuelType == 'Gas'].index.tolist()

    m = pm.ConcreteModel()

    m.gen_set = pm.Set(initialize=Gen.index.tolist())
    m.branch_set = pm.Set(initialize=Branch.index.tolist())
    m.bus_set = pm.Set(initialize=Bus.index.tolist())

    m.gasgen_set = pm.Set(initialize=GasGenerators,
                          within=m.gen_set,
                          ordered=True)

    m.TruthTable = pm.Param(m.gasgen_set,
                            mutable=True,
                            initialize=lambda m, i: (Cur_TruthTable[i]))
    m.P_UB = pm.Param(m.gasgen_set,
                      mutable=False,
                      initialize=lambda m, i: (Gen.DC_RO_OPF_P_UB[i]))
    m.P_LB = pm.Param(m.gasgen_set,
                      mutable=False,
                      initialize=lambda m, i: (Gen.DC_RO_OPF_P_LB[i]))
    #m.P_UB = pm.Var(m.gasgen_set,bounds= lambda m,i : (Gen.DC_RO_OPF_P_UB[i],Gen.DC_RO_OPF_P_UB[i]),initialize=lambda m,i : Gen.DC_OPF_RES[i] )
    #m.P_LB = pm.Var(m.gasgen_set,bounds= lambda m,i : (Gen.Pmin_MW[i],Gen.DC_OPF_RES[i]),initialize=lambda m,i : Gen.DC_OPF_RES[i] )
    m.P = pm.Var(m.gen_set,
                 bounds=lambda m, i: (Gen.Pmin_MW[i], Gen.Pmax_MW[i]),
                 initialize=1)
    m.Pij = pm.Var(m.branch_set,
                   bounds=lambda m, i:
                   (-Branch.RateA_MVA[i], Branch.RateA_MVA[i]),
                   initialize=1)
    m.th = pm.Var(m.bus_set, bounds=(-np.pi, np.pi), initialize=0)
    m.P_Shed = pm.Var(m.gasgen_set, bounds=(0, None))
    m.P_Add = pm.Var(m.gasgen_set, bounds=(0, None))

    def PowerBal_constr(model, i):
        PowerBal = -Bus.PD_MW[i] \
        + sum(m.P[k]   for k in Gen[Gen.Gen_Bus==i].index.tolist()) \
        - sum(m.Pij[k] for k in Branch[Branch.From_Bus==i].index.tolist()) \
        + sum(m.Pij[k] for k in Branch[Branch.To_Bus==i].index.tolist()) \
        ==0
        return PowerBal

    m.PowerBal_constr = pm.Constraint(m.bus_set, rule=PowerBal_constr)

    def Branch_Flow(model, i):
        From_ix = Branch.From_Bus[i]
        To_ix = Branch.To_Bus[i]
        B = Elecdata.Params.BaseMVA / Branch.BR_X_PU[i]
        return m.Pij[i] == (B) * (m.th[From_ix] - m.th[To_ix])

    m.branchflow = pm.Constraint(m.branch_set, rule=Branch_Flow)

    def SlackNode(model, i):
        if Bus.Bus_Type[i] == 3:
            return m.th[i] == 0
        else:
            return pm.Constraint.Skip

    m.slack = pm.Constraint(m.bus_set, rule=SlackNode)

    def Power_UB_LB(model, i):
        Binary_LB = m.TruthTable[i]  # Truth table index
        Binary_UB = 1 - Binary_LB
        return m.P[i] == Binary_UB * m.P_UB[i] + Binary_LB * m.P_LB[i]

    m.Power_UB_LB = pm.Constraint(m.gasgen_set, rule=Power_UB_LB)

    def Costs(model):
        return sum(Gen.CostCoeff_1[k] * m.P[k]
                   for k in m.gen_set) <= Elecdata.Params.C_max_RO

    m.Costs = pm.Constraint(rule=Costs)

    def Shed(model, i):
        return m.P_Shed[i] == Gen.DC_OPF_RES[i] - m.P_LB[i]

    m.shed = pm.Constraint(m.gasgen_set, rule=Shed)

    def Add(model, i):
        return m.P_Add[i] == m.P_UB[i] - Gen.DC_OPF_RES[i]

    m.add = pm.Constraint(m.gasgen_set, rule=Add)

    def DC_OPF_Obj(model):
        return sum(Gen.AddWeight[i] * m.P_Add[i] +
                   Gen.ShedWeight[i] * m.P_Shed[i] for i in m.gasgen_set)

    m.objective = pm.Objective(rule=DC_OPF_Obj,
                               sense=pm.maximize,
                               doc='Define objective function')

    return m
Exemplo n.º 13
0
    # Sub problem
    #---------------------------------------------------------------------------
    #---------------------------------------------------------------------------

    sub = pyo.ConcreteModel()

    # **************************************************************************
    # Sets
    # **************************************************************************

    # Hour sets
    sub.H = pyo.RangeSet(1, len(HOURS)-1)
    sub.H_all = pyo.RangeSet(0, len(HOURS)-1)

    # Set of energy storage resources.
    sub.ESR = pyo.Set(initialize=esr_types)

    # **************************************************************************
    # Parameter
    # **************************************************************************

    # Create a parameter for the load values.
    sub.load_values = pyo.Param(sub.H_all, mutable=True)

    # **************************************************************************
    # Variables
    # **************************************************************************

    # First stage variables

    # no need for declaration of variable types because that is determined by
Exemplo n.º 14
0

def bal_const_rule(m):
    return m.DPh.mass_flow + m.CPh.mass_flow == 100


m.bal_const = pe.Constraint(rule=bal_const_rule)

# Inicializar corrientes
opt.solve(CPh)
opt.solve(DPh)

#####################################
# Modelo de emulsion
#####################################
m.cd = pe.Set(initialize=['prop', 'appl'])  # Conjunto de condiciones

############### Viscosidad de emulsion
m.mu = pe.Var(m.cd, domain=pe.PositiveReals)  # Emulsion viscosity
###############

# Variables compartidas
m.vo = pe.Var(domain=pe.PositiveReals,
              bounds=(0, 1))  # Fraccion volumetrica O/W
m.dM = pe.Var(domain=pe.PositiveReals)  # D32 [mu m]
m.ti = pe.Var(domain=pe.PositiveReals)  # Tension interfacial

m.k = pe.Var(m.cd, domain=pe.PositiveReals)  # Ratio de viscosidades
m.Sr = pe.Var(m.cd, domain=pe.PositiveReals)  # Shear rate

# Variables fijas  y limites
Exemplo n.º 15
0
def create_lineal_model_Alloc(model, set_REF, param_AnchoCaja, param_TipoDist,
                              param_Espacios, param_Demanda, param_Frecuencia,
                              set_RACKS, param_TipoRack, param_Pared,
                              param_Utilizacion, param_Costo):
    ## --------------------- CONJUNTOS ----------------------------
    model.REF = pyo.Set(initialize=set_REF)
    model.RACKS = pyo.Set(initialize=set_RACKS)

    ## ---------------------- PARÁMETROS ----------------------------
    model.AnchoCaja = pyo.Param(model.REF, initialize=param_AnchoCaja)
    model.TipoDist = pyo.Param(model.REF, initialize=param_TipoDist)
    model.Espacios = pyo.Param(model.REF,
                               mutable=True,
                               initialize=param_Espacios)
    model.TipoRack = pyo.Param(model.RACKS, initialize=param_TipoRack)
    model.Pared = pyo.Param(model.RACKS, initialize=param_Pared)
    model.Utilizacion = pyo.Param(model.RACKS, initialize=param_Utilizacion)

    model.Demanda = pyo.Param(model.REF, initialize=param_Demanda)
    model.Frecuencia = pyo.Param(model.REF, initialize=param_Frecuencia)
    model.Costo = pyo.Param(model.RACKS, initialize=param_Costo)

    ## ---------------------- VARIABLES ----------------------------
    model.x = pyo.Var(model.REF, model.RACKS, domain=pyo.Binary)
    model.y = pyo.Var(model.RACKS, domain=pyo.Binary)

    ## ---------------------- FUNCIÓN OBJETIVO ----------------------------
    def ObjFunc(model):
        return sum(model.Demanda[ref] * model.Frecuencia[ref] *
                   model.Costo[rack] * model.x[ref, rack] for ref in model.REF
                   for rack in model.RACKS)

    model.FO = pyo.Objective(rule=ObjFunc)

    ## ---------------------- RESTRICCIONES ----------------------------
    def r1(model, ref):
        return sum(model.x[ref, rack] for rack in model.RACKS) == 1

    model.r1 = pyo.Constraint(model.REF, rule=r1)

    def r2(model, rack):
        return sum(model.AnchoCaja[ref] * model.x[ref, rack] for ref in model.
                   REF) <= 250 * (1 - model.y[rack]) + 750 * (model.y[rack])

    model.r2 = pyo.Constraint(model.RACKS, rule=r2)

    def r3(model, ref, rack):
        return model.x[ref, rack] <= (model.y[rack] * model.TipoDist[ref]) + (
            (1 - model.y[rack]) * (1 - model.TipoDist[ref]))

    model.r3 = pyo.Constraint(model.REF, model.RACKS, rule=r3)

    def r6(model, ref, rack):
        return model.Espacios[ref] * model.x[ref, rack] <= model.TipoRack[rack]

    model.r6 = pyo.Constraint(model.REF, model.RACKS, rule=r6)

    def r8(model, rack):
        return model.y[rack] <= 1 - model.Pared[rack]

    model.r8 = pyo.Constraint(model.RACKS, rule=r8)

    def r9(model, ref, rack):
        return model.x[ref, rack] <= model.Utilizacion[rack]

    model.r9 = pyo.Constraint(model.REF, model.RACKS, rule=r9)
Exemplo n.º 16
0
# -*- coding: utf-8 -*-
"""
Created on Fri May 15 17:48:03 2020

@author: Alessandro Avolio & Leonardo Castellini
"""
#0-1 knapsack problem. We have a maximum number of avaiable trucks with a limited capacity.
# We have an Y demand of X products (sold in pallets) with their Z volume. We have to find
# the optimal number of trucks to being able to deliver all of our products.

import pyomo.environ as pe

####################### ABSTRACT MODEL #################################
TL = pe.AbstractModel(name='Truck loading')
#pallet set
TL.pallet = pe.Set()
#pallet volume (cubic meters)
TL.vol = pe.Param(TL.pallet)
#pallets' demand
TL.qta = pe.Param(TL.pallet)
#tir set
TL.tir = pe.Set()
#trucks' maximum capacity (cubic meters)
TL.maxcap = pe.Param()
#0-1 variable for trucks (used/not used)
TL.y = pe.Var(TL.tir, within=pe.Binary)
#quantity matrix of i pallet in j truck, pallets being non partitionable
TL.x = pe.Var(TL.pallet, TL.tir, within=pe.NonNegativeIntegers)


#objective function, minimize trucks
Exemplo n.º 17
0
def create_model(demand_factor=1.0):

    model = pyo.ConcreteModel()

    # sets
    model.TIME = dae.ContinuousSet(bounds=(0.0, 24.0))
    model.DIS = dae.ContinuousSet(bounds=(0.0, 1.0))
    model.S = pyo.Param(initialize=1)
    model.SCEN = pyo.RangeSet(1, model.S)

    # links
    model.LINK = pyo.Set(initialize=[
        'l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8', 'l9', 'l10', 'l11',
        'l12'
    ])

    def rule_startloc(m, l):
        ll = [
            'l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8', 'l9', 'l10', 'l11',
            'l12'
        ]
        ls = [
            'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11',
            'n12'
        ]
        start_locations = dict(zip(ll, ls))
        return start_locations[l]

    model.lstartloc = pyo.Param(model.LINK,
                                initialize=rule_startloc,
                                within=pyo.Any)

    def rule_endloc(m, l):
        ll = [
            'l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8', 'l9', 'l10', 'l11',
            'l12'
        ]
        ls = [
            'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11',
            'n12', 'n13'
        ]
        end_locations = dict(zip(ll, ls))
        return end_locations[l]

    model.lendloc = pyo.Param(model.LINK,
                              initialize=rule_endloc,
                              within=pyo.Any)

    model.ldiam = pyo.Param(model.LINK, initialize=920.0, mutable=True)

    def rule_llength(m, l):
        if l == 'l1' or l == 'l12':
            return 300.0
        return 100.0

    model.llength = pyo.Param(model.LINK,
                              initialize=rule_llength,
                              mutable=True)

    def rule_ltype(m, l):
        if l == 'l1' or l == 'l12':
            return 'p'
        return 'a'

    model.ltype = pyo.Param(model.LINK, initialize=rule_ltype, within=pyo.Any)

    def link_a_init_rule(m):
        return (l for l in m.LINK if m.ltype[l] == "a")

    model.LINK_A = pyo.Set(initialize=link_a_init_rule)

    def link_p_init_rule(m):
        return (l for l in m.LINK if m.ltype[l] == "p")

    model.LINK_P = pyo.Set(initialize=link_p_init_rule)

    # nodes
    model.NODE = pyo.Set(initialize=[
        'n1', 'n2', 'n3', 'n4', 'n5', 'n6', 'n7', 'n8', 'n9', 'n10', 'n11',
        'n12', 'n13'
    ])

    def rule_pmin(m, n):
        if n == 'n1':
            return 57.0
        elif n == 'n13':
            return 39.0
        else:
            return 34.0

    model.pmin = pyo.Param(model.NODE, initialize=rule_pmin, mutable=True)

    def rule_pmax(m, n):
        if n == 'n13':
            return 41.0
        return 70.0

    model.pmax = pyo.Param(model.NODE, initialize=rule_pmax, mutable=True)

    # supply
    model.SUP = pyo.Set(initialize=[1])
    model.sloc = pyo.Param(model.SUP, initialize='n1', within=pyo.Any)
    model.smin = pyo.Param(model.SUP,
                           within=pyo.NonNegativeReals,
                           initialize=0.000,
                           mutable=True)
    model.smax = pyo.Param(model.SUP,
                           within=pyo.NonNegativeReals,
                           initialize=30,
                           mutable=True)
    model.scost = pyo.Param(model.SUP, within=pyo.NonNegativeReals)

    # demand
    model.DEM = pyo.Set(initialize=[1])
    model.dloc = pyo.Param(model.DEM, initialize='n13', within=pyo.Any)
    model.d = pyo.Param(model.DEM,
                        within=pyo.PositiveReals,
                        initialize=10,
                        mutable=True)

    # physical data

    model.TDEC = pyo.Param(initialize=9.5)

    model.eps = pyo.Param(initialize=0.025, within=pyo.PositiveReals)
    model.z = pyo.Param(initialize=0.80, within=pyo.PositiveReals)
    model.rhon = pyo.Param(initialize=0.72, within=pyo.PositiveReals)
    model.R = pyo.Param(initialize=8314.0, within=pyo.PositiveReals)
    model.M = pyo.Param(initialize=18.0, within=pyo.PositiveReals)
    model.pi = pyo.Param(initialize=3.14, within=pyo.PositiveReals)
    model.nu2 = pyo.Param(within=pyo.PositiveReals, mutable=True)
    model.lam = pyo.Param(model.LINK, within=pyo.PositiveReals, mutable=True)
    model.A = pyo.Param(model.LINK, within=pyo.NonNegativeReals, mutable=True)
    model.Tgas = pyo.Param(initialize=293.15, within=pyo.PositiveReals)
    model.Cp = pyo.Param(initialize=2.34, within=pyo.PositiveReals)
    model.Cv = pyo.Param(initialize=1.85, within=pyo.PositiveReals)
    model.gam = pyo.Param(initialize=model.Cp / model.Cv,
                          within=pyo.PositiveReals)
    model.om = pyo.Param(initialize=(model.gam - 1.0) / model.gam,
                         within=pyo.PositiveReals)

    # scaling and constants
    model.ffac = pyo.Param(within=pyo.PositiveReals,
                           initialize=(1.0e+6 * model.rhon) / (24.0 * 3600.0))
    model.ffac2 = pyo.Param(within=pyo.PositiveReals,
                            initialize=3600.0 / (1.0e+4 * model.rhon))
    model.pfac = pyo.Param(within=pyo.PositiveReals, initialize=1.0e+5)
    model.pfac2 = pyo.Param(within=pyo.PositiveReals, initialize=1.0e-5)
    model.dfac = pyo.Param(within=pyo.PositiveReals, initialize=1.0e-3)
    model.lfac = pyo.Param(within=pyo.PositiveReals, initialize=1.0e+3)

    model.c1 = pyo.Param(model.LINK, within=pyo.PositiveReals, mutable=True)
    model.c2 = pyo.Param(model.LINK, within=pyo.PositiveReals, mutable=True)
    model.c3 = pyo.Param(model.LINK, within=pyo.PositiveReals, mutable=True)
    model.c4 = pyo.Param(within=pyo.PositiveReals, mutable=True)

    # cost factors
    model.ce = pyo.Param(initialize=0.1, within=pyo.NonNegativeReals)
    model.cd = pyo.Param(initialize=1.0e+6, within=pyo.NonNegativeReals)
    model.cT = pyo.Param(initialize=1.0e+6, within=pyo.NonNegativeReals)
    model.cs = pyo.Param(initialize=0.0, within=pyo.NonNegativeReals)

    # define stochastic info
    model.rand_d = pyo.Param(model.SCEN,
                             model.DEM,
                             within=pyo.NonNegativeReals,
                             mutable=True)

    # convert units for input data
    def rescale_rule(m):

        for i in m.LINK:
            m.ldiam[i] = m.ldiam[i] * m.dfac
            m.llength[i] = m.llength[i] * m.lfac
            # m.dx[i] = m.llength[i]/float(m.DIS.last())

        for i in m.SUP:
            m.smin[i] = m.smin[
                i] * m.ffac * m.ffac2  # from scmx106/day to kg/s and then to scmx10-4/hr
            m.smax[i] = m.smax[
                i] * m.ffac * m.ffac2  # from scmx106/day to kg/s and then to scmx10-4/hr

        for i in m.DEM:
            m.d[i] = m.d[i] * m.ffac * m.ffac2

        for i in m.NODE:
            m.pmin[i] = m.pmin[
                i] * m.pfac * m.pfac2  # from bar to Pascals and then to bar
            m.pmax[i] = m.pmax[
                i] * m.pfac * m.pfac2  # from bar to Pascals and then to bar

    rescale_rule(model)

    def compute_constants(m):
        for i in m.LINK:
            m.lam[i] = (2.0 * pyo.log10(3.7 * m.ldiam[i] /
                                        (m.eps * m.dfac)))**(-2.0)
            m.A[i] = (1.0 / 4.0) * m.pi * m.ldiam[i] * m.ldiam[i]
            m.nu2 = m.gam * m.z * m.R * m.Tgas / m.M
            m.c1[i] = (m.pfac2 / m.ffac2) * (m.nu2 / m.A[i])
            m.c2[i] = m.A[i] * (m.ffac2 / m.pfac2)
            m.c3[i] = m.A[i] * (m.pfac2 / m.ffac2) * (
                8.0 * m.lam[i] * m.nu2) / (m.pi * m.pi * (m.ldiam[i]**5.0))
            m.c4 = (1 / m.ffac2) * (m.Cp * m.Tgas)

    compute_constants(model)

    # set stochastic demands
    def compute_demands_rule(m):
        for k in m.SCEN:
            for j in m.DEM:
                m.rand_d[k, j] = demand_factor * m.d[j]

    compute_demands_rule(model)

    def stochd_init(m, k, j, t):
        # What it should be to match description in paper
        # if t < m.TDEC:
        #     return m.d[j]
        # if t >= m.TDEC and t < m.TDEC+5:
        #     return m.rand_d[k,j]
        # if t >= m.TDEC+5:
        #     return m.d[j]
        if t < m.TDEC + 1:
            return m.d[j]
        if t >= m.TDEC + 1 and t < m.TDEC + 1 + 4.5:
            return m.rand_d[k, j]
        if t >= m.TDEC + 1 + 4.5:
            return m.d[j]

    model.stochd = pyo.Param(model.SCEN,
                             model.DEM,
                             model.TIME,
                             within=pyo.PositiveReals,
                             mutable=True,
                             default=stochd_init)

    # define temporal variables
    def p_bounds_rule(m, k, j, t):
        return pyo.value(m.pmin[j]), pyo.value(m.pmax[j])

    model.p = pyo.Var(model.SCEN,
                      model.NODE,
                      model.TIME,
                      bounds=p_bounds_rule,
                      initialize=50.0)

    model.dp = pyo.Var(model.SCEN,
                       model.LINK_A,
                       model.TIME,
                       bounds=(0.0, 100.0),
                       initialize=10.0)
    model.fin = pyo.Var(model.SCEN,
                        model.LINK,
                        model.TIME,
                        bounds=(1.0, 500.0),
                        initialize=100.0)
    model.fout = pyo.Var(model.SCEN,
                         model.LINK,
                         model.TIME,
                         bounds=(1.0, 500.0),
                         initialize=100.0)

    def s_bounds_rule(m, k, j, t):
        return 0.01, pyo.value(m.smax[j])

    model.s = pyo.Var(model.SCEN,
                      model.SUP,
                      model.TIME,
                      bounds=s_bounds_rule,
                      initialize=10.0)
    model.dem = pyo.Var(model.SCEN, model.DEM, model.TIME, initialize=100.0)
    model.pow = pyo.Var(model.SCEN,
                        model.LINK_A,
                        model.TIME,
                        bounds=(0.0, 3000.0),
                        initialize=1000.0)
    model.slack = pyo.Var(model.SCEN,
                          model.LINK,
                          model.TIME,
                          model.DIS,
                          bounds=(0.0, None),
                          initialize=10.0)

    # define spatio-temporal variables
    # average 55.7278214666423
    model.px = pyo.Var(model.SCEN,
                       model.LINK,
                       model.TIME,
                       model.DIS,
                       bounds=(10.0, 100.0),
                       initialize=50.0)
    # average 43.19700578593625
    model.fx = pyo.Var(model.SCEN,
                       model.LINK,
                       model.TIME,
                       model.DIS,
                       bounds=(1.0, 100.0),
                       initialize=100.0)

    # define derivatives
    model.dpxdt = dae.DerivativeVar(model.px, wrt=model.TIME, initialize=0)
    model.dpxdx = dae.DerivativeVar(model.px, wrt=model.DIS, initialize=0)
    model.dfxdt = dae.DerivativeVar(model.fx, wrt=model.TIME, initialize=0)
    model.dfxdx = dae.DerivativeVar(model.fx, wrt=model.DIS, initialize=0)

    # ----------- MODEL --------------

    # compressor equations
    def powereq_rule(m, j, i, t):
        return m.pow[j, i, t] == m.c4 * m.fin[j, i, t] * (
            ((m.p[j, m.lstartloc[i], t] + m.dp[j, i, t]) /
             m.p[j, m.lstartloc[i], t])**m.om - 1.0)

    model.powereq = pyo.Constraint(model.SCEN,
                                   model.LINK_A,
                                   model.TIME,
                                   rule=powereq_rule)

    # cvar model
    model.cvar_lambda = pyo.Param(initialize=0.0)
    model.nu = pyo.Var(initialize=100.0)
    model.phi = pyo.Var(model.SCEN, bounds=(0.0, None), initialize=100.0)

    def cvarcost_rule(m):
        return (1.0 / m.S) * sum(
            (m.phi[k] / (1.0 - 0.95) + m.nu) for k in m.SCEN)

    model.cvarcost = pyo.Expression(rule=cvarcost_rule)

    # node balances
    def nodeeq_rule(m, k, i, t):
        return sum(m.fout[k, j, t] for j in m.LINK if m.lendloc[j] == i) +  \
               sum(m.s[k, j, t] for j in m.SUP if m.sloc[j] == i) -         \
               sum(m.fin[k, j, t] for j in m.LINK if m.lstartloc[j] == i) - \
               sum(m.dem[k, j, t] for j in m.DEM if m.dloc[j] == i) == 0.0

    model.nodeeq = pyo.Constraint(model.SCEN,
                                  model.NODE,
                                  model.TIME,
                                  rule=nodeeq_rule)

    # boundary conditions flow
    def flow_start_rule(m, j, i, t):
        return m.fx[j, i, t, m.DIS.first()] == m.fin[j, i, t]

    model.flow_start = pyo.Constraint(model.SCEN,
                                      model.LINK,
                                      model.TIME,
                                      rule=flow_start_rule)

    def flow_end_rule(m, j, i, t):
        return m.fx[j, i, t, m.DIS.last()] == m.fout[j, i, t]

    model.flow_end = pyo.Constraint(model.SCEN,
                                    model.LINK,
                                    model.TIME,
                                    rule=flow_end_rule)

    # First PDE for gas network model
    def flow_rule(m, j, i, t, k):
        if t == m.TIME.first() or k == m.DIS.last():
            return pyo.Constraint.Skip  # Do not apply pde at initial time or final location
        return m.dpxdt[j, i, t, k] / 3600.0 + m.c1[i] / m.llength[i] * m.dfxdx[
            j, i, t, k] == 0

    model.flow = pyo.Constraint(model.SCEN,
                                model.LINK,
                                model.TIME,
                                model.DIS,
                                rule=flow_rule)

    # Second PDE for gas network model
    def press_rule(m, j, i, t, k):
        if t == m.TIME.first() or k == m.DIS.last():
            return pyo.Constraint.Skip  # Do not apply pde at initial time or final location
        return m.dfxdt[j, i, t, k] / 3600 == -m.c2[i] / m.llength[i] * m.dpxdx[
            j, i, t, k] - m.slack[j, i, t, k]

    model.press = pyo.Constraint(model.SCEN,
                                 model.LINK,
                                 model.TIME,
                                 model.DIS,
                                 rule=press_rule)

    def slackeq_rule(m, j, i, t, k):
        if t == m.TIME.last():
            return pyo.Constraint.Skip
        return m.slack[j, i, t, k] * m.px[j, i, t, k] == m.c3[i] * m.fx[
            j, i, t, k] * m.fx[j, i, t, k]

    model.slackeq = pyo.Constraint(model.SCEN,
                                   model.LINK,
                                   model.TIME,
                                   model.DIS,
                                   rule=slackeq_rule)

    # boundary conditions pressure, passive links
    def presspas_start_rule(m, j, i, t):
        return m.px[j, i, t, m.DIS.first()] == m.p[j, m.lstartloc[i], t]

    model.presspas_start = pyo.Constraint(model.SCEN,
                                          model.LINK_P,
                                          model.TIME,
                                          rule=presspas_start_rule)

    def presspas_end_rule(m, j, i, t):
        return m.px[j, i, t, m.DIS.last()] == m.p[j, m.lendloc[i], t]

    model.presspas_end = pyo.Constraint(model.SCEN,
                                        model.LINK_P,
                                        model.TIME,
                                        rule=presspas_end_rule)

    # boundary conditions pressure, active links
    def pressact_start_rule(m, j, i, t):
        return m.px[j, i, t,
                    m.DIS.first()] == m.p[j, m.lstartloc[i], t] + m.dp[j, i, t]

    model.pressact_start = pyo.Constraint(model.SCEN,
                                          model.LINK_A,
                                          model.TIME,
                                          rule=pressact_start_rule)

    def pressact_end_rule(m, j, i, t):
        return m.px[j, i, t, m.DIS.last()] == m.p[j, m.lendloc[i], t]

    model.pressact_end = pyo.Constraint(model.SCEN,
                                        model.LINK_A,
                                        model.TIME,
                                        rule=pressact_end_rule)

    # fix pressure at supply nodes
    def suppres_rule(m, k, j, t):
        return m.p[k, m.sloc[j], t] == m.pmin[m.sloc[j]]

    model.suppres = pyo.Constraint(model.SCEN,
                                   model.SUP,
                                   model.TIME,
                                   rule=suppres_rule)

    # discharge pressure for compressors
    def dispress_rule(m, j, i, t):
        return m.p[j, m.lstartloc[i], t] + m.dp[j, i,
                                                t] <= m.pmax[m.lstartloc[i]]

    model.dispress = pyo.Constraint(model.SCEN,
                                    model.LINK_A,
                                    model.TIME,
                                    rule=dispress_rule)

    # ss constraints
    def flow_ss_rule(m, j, i, k):
        if k == m.DIS.last():
            return pyo.Constraint.Skip
        return m.dfxdx[j, i, m.TIME.first(), k] == 0.0

    model.flow_ss = pyo.Constraint(model.SCEN,
                                   model.LINK,
                                   model.DIS,
                                   rule=flow_ss_rule)

    def pres_ss_rule(m, j, i, k):
        if k == m.DIS.last():
            return pyo.Constraint.Skip
        return 0.0 == -m.c2[i] / m.llength[i] * m.dpxdx[
            j, i, m.TIME.first(), k] - m.slack[j, i, m.TIME.first(), k]

    model.pres_ss = pyo.Constraint(model.SCEN,
                                   model.LINK,
                                   model.DIS,
                                   rule=pres_ss_rule)

    # non-anticipativity constraints
    def nonantdq_rule(m, j, i, t):
        if j == 1:
            return pyo.Constraint.Skip
        if t >= m.TDEC + 1:
            return pyo.Constraint.Skip
        return m.dp[j, i, t] == m.dp[1, i, t]

    model.nonantdq = pyo.Constraint(model.SCEN,
                                    model.LINK_A,
                                    model.TIME,
                                    rule=nonantdq_rule)

    def nonantde_rule(m, j, i, t):
        if j == 1:
            return pyo.Constraint.Skip
        if t >= m.TDEC + 1:
            return pyo.Constraint.Skip
        return m.dem[j, i, t] == m.dem[1, i, t]

    model.nonantde = pyo.Constraint(model.SCEN,
                                    model.DEM,
                                    model.TIME,
                                    rule=nonantde_rule)

    # discretize model
    discretizer = pyo.TransformationFactory('dae.finite_difference')
    discretizer.apply_to(model, nfe=1, wrt=model.DIS, scheme='FORWARD')

    discretizer2 = pyo.TransformationFactory('dae.collocation')
    #discretizer2.apply_to(model, nfe=47, ncp=1, wrt=model.TIME, scheme='LAGRANGE-RADAU')

    # discretizer.apply_to(model, nfe=48, wrt=model.TIME, scheme='BACKWARD')

    # What it should be to match description in paper
    discretizer.apply_to(model, nfe=48, wrt=model.TIME, scheme='BACKWARD')

    TimeStep = model.TIME[2] - model.TIME[1]

    def supcost_rule(m, k):
        return sum(m.cs * m.s[k, j, t] * TimeStep for j in m.SUP
                   for t in m.TIME.get_finite_elements())

    model.supcost = pyo.Expression(model.SCEN, rule=supcost_rule)

    def boostcost_rule(m, k):
        return sum(m.ce * m.pow[k, j, t] * TimeStep for j in m.LINK_A
                   for t in m.TIME.get_finite_elements())

    model.boostcost = pyo.Expression(model.SCEN, rule=boostcost_rule)

    def trackcost_rule(m, k):
        return sum(m.cd * (m.dem[k, j, t] - m.stochd[k, j, t])**2.0
                   for j in m.DEM for t in m.TIME.get_finite_elements())

    model.trackcost = pyo.Expression(model.SCEN, rule=trackcost_rule)

    def sspcost_rule(m, k):
        return sum(
            m.cT *
            (m.px[k, i, m.TIME.last(), j] - m.px[k, i, m.TIME.first(), j])**2.0
            for i in m.LINK for j in m.DIS)

    model.sspcost = pyo.Expression(model.SCEN, rule=sspcost_rule)

    def ssfcost_rule(m, k):
        return sum(
            m.cT *
            (m.fx[k, i, m.TIME.last(), j] - m.fx[k, i, m.TIME.first(), j])**2.0
            for i in m.LINK for j in m.DIS)

    model.ssfcost = pyo.Expression(model.SCEN, rule=ssfcost_rule)

    def cost_rule(m, k):
        return 1e-6 * (m.supcost[k] + m.boostcost[k] + m.trackcost[k] +
                       m.sspcost[k] + m.ssfcost[k])

    model.cost = pyo.Expression(model.SCEN, rule=cost_rule)

    def mcost_rule(m):
        return sum(m.cost[k] for k in m.SCEN)

    model.mcost = pyo.Expression(rule=mcost_rule)

    model.FirstStageCost = pyo.Expression(expr=0.0)
    model.SecondStageCost = pyo.Expression(rule=mcost_rule)

    model.obj = pyo.Objective(expr=model.FirstStageCost +
                              model.SecondStageCost)

    return model
Exemplo n.º 18
0
def pysp_instance_creation_callback(scenario_name,
                                    use_integer=False,
                                    sense=pyo.minimize,
                                    crops_multiplier=1):
    # long function to create the entire model
    # scenario_name is a string (e.g. AboveAverageScenario0)
    #
    # Returns a concrete model for the specified scenario

    # scenarios come in groups of three
    scengroupnum = sputils.extract_num(scenario_name)
    scenario_base_name = scenario_name.rstrip("0123456789")

    model = pyo.ConcreteModel()

    def crops_init(m):
        retval = []
        for i in range(crops_multiplier):
            retval.append("WHEAT" + str(i))
            retval.append("CORN" + str(i))
            retval.append("SUGAR_BEETS" + str(i))
        return retval

    model.CROPS = pyo.Set(initialize=crops_init)

    #
    # Parameters
    #

    model.TOTAL_ACREAGE = 500.0 * crops_multiplier

    def _scale_up_data(indict):
        outdict = {}
        for i in range(crops_multiplier):
            for crop in ['WHEAT', 'CORN', 'SUGAR_BEETS']:
                outdict[crop + str(i)] = indict[crop]
        return outdict

    model.PriceQuota = _scale_up_data({
        'WHEAT': 100000.0,
        'CORN': 100000.0,
        'SUGAR_BEETS': 6000.0
    })

    model.SubQuotaSellingPrice = _scale_up_data({
        'WHEAT': 170.0,
        'CORN': 150.0,
        'SUGAR_BEETS': 36.0
    })

    model.SuperQuotaSellingPrice = _scale_up_data({
        'WHEAT': 0.0,
        'CORN': 0.0,
        'SUGAR_BEETS': 10.0
    })

    model.CattleFeedRequirement = _scale_up_data({
        'WHEAT': 200.0,
        'CORN': 240.0,
        'SUGAR_BEETS': 0.0
    })

    model.PurchasePrice = _scale_up_data({
        'WHEAT': 238.0,
        'CORN': 210.0,
        'SUGAR_BEETS': 100000.0
    })

    model.PlantingCostPerAcre = _scale_up_data({
        'WHEAT': 150.0,
        'CORN': 230.0,
        'SUGAR_BEETS': 260.0
    })

    #
    # Stochastic Data
    #
    Yield = {}
    Yield['BelowAverageScenario'] = \
        {'WHEAT':2.0,'CORN':2.4,'SUGAR_BEETS':16.0}
    Yield['AverageScenario'] = \
        {'WHEAT':2.5,'CORN':3.0,'SUGAR_BEETS':20.0}
    Yield['AboveAverageScenario'] = \
        {'WHEAT':3.0,'CORN':3.6,'SUGAR_BEETS':24.0}

    def Yield_init(m, cropname):
        # yield as in "crop yield"
        crop_base_name = cropname.rstrip("0123456789")
        if scengroupnum != 0:
            return Yield[scenario_base_name][
                crop_base_name] + farmerstream.rand()
        else:
            return Yield[scenario_base_name][crop_base_name]

    model.Yield = pyo.Param(model.CROPS,
                            within=pyo.NonNegativeReals,
                            initialize=Yield_init,
                            mutable=True)

    #
    # Variables
    #

    if (use_integer):
        model.DevotedAcreage = pyo.Var(model.CROPS,
                                       within=pyo.NonNegativeIntegers,
                                       bounds=(0.0, model.TOTAL_ACREAGE))
    else:
        model.DevotedAcreage = pyo.Var(model.CROPS,
                                       bounds=(0.0, model.TOTAL_ACREAGE))

    model.QuantitySubQuotaSold = pyo.Var(model.CROPS, bounds=(0.0, None))
    model.QuantitySuperQuotaSold = pyo.Var(model.CROPS, bounds=(0.0, None))
    model.QuantityPurchased = pyo.Var(model.CROPS, bounds=(0.0, None))

    #
    # Constraints
    #

    def ConstrainTotalAcreage_rule(model):
        return pyo.sum_product(model.DevotedAcreage) <= model.TOTAL_ACREAGE

    model.ConstrainTotalAcreage = pyo.Constraint(
        rule=ConstrainTotalAcreage_rule)

    def EnforceCattleFeedRequirement_rule(model, i):
        return model.CattleFeedRequirement[i] <= (
            model.Yield[i] * model.DevotedAcreage[i]
        ) + model.QuantityPurchased[i] - model.QuantitySubQuotaSold[
            i] - model.QuantitySuperQuotaSold[i]

    model.EnforceCattleFeedRequirement = pyo.Constraint(
        model.CROPS, rule=EnforceCattleFeedRequirement_rule)

    def LimitAmountSold_rule(model, i):
        return model.QuantitySubQuotaSold[i] + model.QuantitySuperQuotaSold[
            i] - (model.Yield[i] * model.DevotedAcreage[i]) <= 0.0

    model.LimitAmountSold = pyo.Constraint(model.CROPS,
                                           rule=LimitAmountSold_rule)

    def EnforceQuotas_rule(model, i):
        return (0.0, model.QuantitySubQuotaSold[i], model.PriceQuota[i])

    model.EnforceQuotas = pyo.Constraint(model.CROPS, rule=EnforceQuotas_rule)

    # Stage-specific cost computations;

    def ComputeFirstStageCost_rule(model):
        return pyo.sum_product(model.PlantingCostPerAcre, model.DevotedAcreage)

    model.FirstStageCost = pyo.Expression(rule=ComputeFirstStageCost_rule)

    def ComputeSecondStageCost_rule(model):
        expr = pyo.sum_product(model.PurchasePrice, model.QuantityPurchased)
        expr -= pyo.sum_product(model.SubQuotaSellingPrice,
                                model.QuantitySubQuotaSold)
        expr -= pyo.sum_product(model.SuperQuotaSellingPrice,
                                model.QuantitySuperQuotaSold)
        return expr

    model.SecondStageCost = pyo.Expression(rule=ComputeSecondStageCost_rule)

    def total_cost_rule(model):
        if (sense == pyo.minimize):
            return model.FirstStageCost + model.SecondStageCost
        return -model.FirstStageCost - model.SecondStageCost

    model.Total_Cost_Objective = pyo.Objective(rule=total_cost_rule,
                                               sense=sense)

    return model
Exemplo n.º 19
0
def create_scopf_model(model_data,
                       include_feasibility_slack=False,
                       base_point=BasePointType.FLATSTART,
                       ptdf_options=None):

    ptdf_options = lpu.populate_default_ptdf_options(ptdf_options)

    baseMVA = model_data.data['system']['baseMVA']
    lpu.check_and_scale_ptdf_options(ptdf_options, baseMVA)

    md = model_data.clone_in_service()
    tx_utils.scale_ModelData_to_pu(md, inplace=True)

    gens = dict(md.elements(element_type='generator'))
    buses = dict(md.elements(element_type='bus'))
    branches = dict(md.elements(element_type='branch'))
    loads = dict(md.elements(element_type='load'))
    shunts = dict(md.elements(element_type='shunt'))

    dc_branches = dict(md.elements(element_type='dc_branch'))
    contingencies = dict(md.elements(element_type='contingency'))

    gen_attrs = md.attributes(element_type='generator')
    ## to keep things in order
    buses_idx = tuple(buses.keys())
    branches_idx = tuple(branches.keys())

    inlet_branches_by_bus, outlet_branches_by_bus = \
        tx_utils.inlet_outlet_branches_by_bus(branches, buses)
    gens_by_bus = tx_utils.gens_by_bus(buses, gens)

    model = pyo.ConcreteModel()

    ### declare (and fix) the loads at the buses
    bus_p_loads, _ = tx_utils.dict_of_bus_loads(buses, loads)

    libbus.declare_var_pl(model, buses_idx, initialize=bus_p_loads)
    model.pl.fix()

    ### declare the fixed shunts at the buses
    _, bus_gs_fixed_shunts = tx_utils.dict_of_bus_fixed_shunts(buses, shunts)

    ### declare the generator real power
    pg_init = {
        k: (gen_attrs['p_min'][k] + gen_attrs['p_max'][k]) / 2.0
        for k in gen_attrs['pg']
    }
    libgen.declare_var_pg(model,
                          gen_attrs['names'],
                          initialize=pg_init,
                          bounds=zip_items(gen_attrs['p_min'],
                                           gen_attrs['p_max']))

    ### include the feasibility slack for the system balance
    p_rhs_kwargs = {}
    if include_feasibility_slack:
        p_marginal_slack_penalty = _validate_and_extract_slack_penalty(md)
        p_rhs_kwargs, penalty_expr = _include_system_feasibility_slack(
            model, bus_p_loads, gen_attrs, p_marginal_slack_penalty)

    if dc_branches:
        dcpf_bounds = dict()
        for k, k_dict in dc_branches.items():
            kp_max = k_dict['rating_long_term']
            if kp_max is None:
                dcpf_bounds[k] = (None, None)
            else:
                dcpf_bounds[k] = (-kp_max, kp_max)
        libbranch.declare_var_dcpf(
            model=model,
            index_set=dc_branches.keys(),
            initialize=0.,
            bounds=dcpf_bounds,
        )
        dc_inlet_branches_by_bus, dc_outlet_branches_by_bus = \
                tx_utils.inlet_outlet_branches_by_bus(dc_branches, buses)
    else:
        dc_inlet_branches_by_bus = None
        dc_outlet_branches_by_bus = None

    ### declare the p balance
    libbus.declare_eq_p_balance_ed(model=model,
                                   index_set=buses_idx,
                                   bus_p_loads=bus_p_loads,
                                   gens_by_bus=gens_by_bus,
                                   bus_gs_fixed_shunts=bus_gs_fixed_shunts,
                                   **p_rhs_kwargs)

    ### declare net withdraw expression for use in PTDF power flows
    libbus.declare_expr_p_net_withdraw_at_bus(
        model=model,
        index_set=buses_idx,
        bus_p_loads=bus_p_loads,
        gens_by_bus=gens_by_bus,
        bus_gs_fixed_shunts=bus_gs_fixed_shunts,
        dc_inlet_branches_by_bus=dc_inlet_branches_by_bus,
        dc_outlet_branches_by_bus=dc_outlet_branches_by_bus,
    )

    ### add "blank" power flow expressions
    libbranch.declare_expr_pf(
        model=model,
        index_set=branches_idx,
    )

    ### add "blank" power flow expressions
    model._contingencies = pyo.Set(initialize=contingencies.keys())
    model._branches = pyo.Set(initialize=branches_idx)
    ### NOTE: important that this not be dense, we'll add elements
    ###       as we find violations
    model._contingency_set = pyo.Set(within=model._contingencies *
                                     model._branches)
    model.pfc = pyo.Expression(model._contingency_set)

    ## Do and store PTDF calculation
    reference_bus = md.data['system']['reference_bus']

    PTDF = ptdf_utils.VirtualPTDFMatrix(branches, buses, reference_bus, base_point, ptdf_options,\
                                        contingencies=contingencies, branches_keys=branches_idx, buses_keys=buses_idx)

    model._PTDF = PTDF
    model._ptdf_options = ptdf_options

    if not ptdf_options['lazy']:
        raise RuntimeError("scopf only supports lazy constraint generation")

    ### add "blank" real power flow limits
    libbranch.declare_ineq_p_branch_thermal_bounds(
        model=model,
        index_set=branches_idx,
        branches=branches,
        p_thermal_limits=None,
        approximation_type=None,
    )

    ### add "blank" real power flow limits
    libbranch.declare_ineq_p_contingency_branch_thermal_bounds(
        model=model,
        index_set=model._contingency_set,
        pc_thermal_limits=None,
        approximation_type=None,
    )

    ### add helpers for tracking monitored branches
    lpu.add_monitored_flow_tracker(model)

    ### add initial branches to monitored set
    lpu.add_initial_monitored_branches(model, branches, branches_idx,
                                       ptdf_options, PTDF)

    ### declare the generator cost objective
    libgen.declare_expression_pgqg_operating_cost(model=model,
                                                  index_set=gen_attrs['names'],
                                                  p_costs=gen_attrs['p_cost'])

    obj_expr = sum(model.pg_operating_cost[gen_name]
                   for gen_name in model.pg_operating_cost)
    if include_feasibility_slack:
        obj_expr += penalty_expr

    model.obj = pyo.Objective(expr=obj_expr)

    return model, md
Exemplo n.º 20
0
import pyomo.environ as pyo
from pyomo.opt import SolverFactory

## ----------------------- MODELO -------------------------------
opt = SolverFactory(
    'cplex',
    executable=
    "C:\\Program Files\\IBM\\ILOG\\CPLEX_Studio1210\\cplex\\bin\\x64_win64\\cplex"
)
#opt = SolverFactory('glpk')
model = pyo.AbstractModel()

## --------------------- CONJUNTOS ----------------------------
model.REF = pyo.Set()
model.RACKS = pyo.Set()

## ---------------------- PARÁMETROS ----------------------------
model.AnchoCaja = pyo.Param(model.REF)
model.TipoDist = pyo.Param(model.REF)
model.Espacios = pyo.Param(model.REF, mutable=True)
model.TipoRack = pyo.Param(model.RACKS)
model.Pared = pyo.Param(model.RACKS)
model.Utilizacion = pyo.Param(model.RACKS)

model.Demanda = pyo.Param(model.REF)
model.Frecuencia = pyo.Param(model.REF)
model.Costo = pyo.Param(model.RACKS)

## ---------------------- VARIABLES ----------------------------
model.x = pyo.Var(model.REF, model.RACKS, domain=pyo.Binary)
model.y = pyo.Var(model.RACKS, domain=pyo.Binary)
Exemplo n.º 21
0
    def createPrimal(self):
        """Create the primal pyomo model.  
        
        This is used to compute flows after interdiction.  The interdiction is stored in arc_commodity_data.xbar."""

        model = pe.ConcreteModel()
        # Tell pyomo to read in dual-variable information from the solver
        model.dual = pe.Suffix(direction=pe.Suffix.IMPORT)

        # Add the sets
        model.node_set = pe.Set(initialize=self.node_set)
        model.edge_set = pe.Set(initialize=self.arc_set, dimen=2)
        model.commodity_set = pe.Set(initialize=self.commodity_set)

        # Create the variables
        model.y = pe.Var(model.edge_set * model.commodity_set,
                         domain=pe.NonNegativeReals)
        model.UnsatSupply = pe.Var(model.node_set * model.commodity_set,
                                   domain=pe.NonNegativeReals)
        model.UnsatDemand = pe.Var(model.node_set * model.commodity_set,
                                   domain=pe.NonNegativeReals)

        # Create the objective
        def obj_rule(model):
            return sum(
                (data['Cost'] + data['xbar'] *
                 (2 * self.nCmax + 1)) * model.y[e]
                for e, data in self.arc_commodity_data.iterrows()) + sum(
                    self.nCmax * (model.UnsatSupply[n] + model.UnsatDemand[n])
                    for n, data in self.node_commodity_data.iterrows())

        model.OBJ = pe.Objective(rule=obj_rule, sense=pe.minimize)

        # Create the constraints, one for each node
        def flow_bal_rule(model, n, k):
            tmp = self.arc_data.reset_index()
            successors = tmp.ix[tmp.StartNode == n, 'EndNode'].values
            predecessors = tmp.ix[tmp.EndNode == n, 'StartNode'].values
            lhs = sum(model.y[(i, n, k)]
                      for i in predecessors) - sum(model.y[(n, i, k)]
                                                   for i in successors)
            imbalance = self.node_commodity_data['SupplyDemand'].get((n, k), 0)
            supply_node = int(imbalance < 0)
            demand_node = int(imbalance > 0)
            rhs = (imbalance + model.UnsatSupply[n, k] * (supply_node) -
                   model.UnsatDemand[n, k] * (demand_node))
            constr = (lhs == rhs)
            if isinstance(constr, bool):
                return pe.Constraint.Skip
            return constr

        model.FlowBalance = pe.Constraint(model.node_set * model.commodity_set,
                                          rule=flow_bal_rule)

        # Capacity constraints, one for each edge and commodity
        def capacity_rule(model, i, j, k):
            capacity = self.arc_commodity_data['Capacity'].get((i, j, k), -1)
            if capacity < 0:
                return pe.Constraint.Skip
            return model.y[(i, j, k)] <= capacity

        model.Capacity = pe.Constraint(model.edge_set * model.commodity_set,
                                       rule=capacity_rule)

        # Joint capacity constraints, one for each edge
        def joint_capacity_rule(model, i, j):
            capacity = self.arc_data['Capacity'].get((i, j), -1)
            if capacity < 0:
                return pe.Constraint.Skip
            return sum(model.y[(i, j, k)]
                       for k in self.commodity_set) <= capacity

        model.JointCapacity = pe.Constraint(model.edge_set,
                                            rule=joint_capacity_rule)

        # Store the model
        self.primal = model
        'pl': 0.05
    }
}
#                       jan, feb, mar,apr, may, jun
market_limits = {
    'p1': [500, 600, 300, 200, 0, 500],
    'p2': [1000, 500, 600, 300, 100, 500],
    'p3': [300, 200, 0, 400, 500, 100],
    'p4': [300, 0, 0, 500, 100, 300],
    'p5': [800, 400, 500, 200, 1000, 1100],
    'p6': [200, 300, 400, 0, 300, 500],
    'p7': [100, 150, 100, 100, 0, 60]
}

m = pe.ConcreteModel()
m.months = pe.Set(initialize=months)
m.prods = pe.Set(initialize=items)
m.equips = pe.Set(initialize=eqtype)

# quantity of products that are to be produced for each month
m.made = pe.Var(items, months, initialize=0, within=pe.NonNegativeReals)
m.sold = pe.Var(items, months, initialize=0, within=pe.NonNegativeReals)
m.stored = pe.Var(items, months, initialize=0, within=pe.NonNegativeReals)


def rule_objective(m):
    # profit contribution per unit per item per month
    # storage cost 0.5 dollar per unit.
    expr1 = sum(m.sold[(pi, mon)] * profit[pi] - m.stored[(pi, mon)] * 0.5
                for pi, mon in product(items, months))
    return expr1
Exemplo n.º 23
0
def _rental(linear=False, **kwargs):
    """
    Factory method for the Rental scheduling problem.

    Parameters
    ----------
    linear : :py:obj:`bool`, optional
        Determines whether decision variables will be
        Reals (True) or Integer (False).
    **kwargs : optional
        if any given, returns pyomo concrete model instead, with these passed
        into pyomo's `create_instance`.
    """
    def _obj_expression(model):
        """Objective Expression: Minimizing Number of Workers"""
        my_expr = 0
        for (period, plan) in model.PlanToPeriod:
            my_expr += model.PlanCosts[plan] * model.NumRent[(period, plan)]
        return my_expr

    def _period_reqs_constraint_rule(model, p):
        """Constraints for having enough workers per period"""
        num_periods = len(model.Periods)
        my_sum = 0
        sum_terms = []
        for (period, plan) in model.PlanToPeriod:
            # Get index of current period
            ind = model.Periods.ord(p)
            # Get effective periods based on PlanLength
            periods_in_plan = [
                model.Periods[((ind - 1 - pl) % num_periods) + 1]
                for pl in range(model.PlanLengths[plan])
            ]
            periods_in_plan = [
                per for per in periods_in_plan
                if (per, plan) in model.PlanToPeriod
            ]
            # Sum up how many rented in effective periods
            # new_terms makes sure that not adding same term again
            new_terms = [(p_in_plan, plan) for p_in_plan in periods_in_plan
                         if (p_in_plan, plan) not in sum_terms]
            my_sum += sum([model.NumRent[term] for term in new_terms])
            sum_terms.extend(new_terms)
        return my_sum >= model.PeriodReqs[p]

    # Create the abstract model & dual suffix
    model = pyo.AbstractModel()
    model.dual = pyo.Suffix(direction=pyo.Suffix.IMPORT)
    # Define sets/params that are always used
    model.Periods = pyo.Set(ordered=True)
    model.Plans = pyo.Set()
    model.PlanToPeriod = pyo.Set(dimen=2)
    model.PeriodReqs = pyo.Param(model.Periods)
    model.PlanCosts = pyo.Param(model.Plans)
    model.PlanLengths = pyo.Param(model.Plans)
    # Define decision variables
    model.NumRent = pyo.Var(
        model.PlanToPeriod,
        within=pyo.NonNegativeReals if linear else pyo.NonNegativeIntegers)
    # Define objective & constraints
    model.OBJ = pyo.Objective(rule=_obj_expression, sense=pyo.minimize)
    model.PeriodReqsConstraint = pyo.Constraint(
        model.Periods, rule=_period_reqs_constraint_rule)
    # Check if returning concrete or abstract model
    if kwargs:
        return model.create_instance(**kwargs)
    else:
        return model
Exemplo n.º 24
0
def net_im_lp_model(env,
                    window_size=np.Inf,
                    perfect_information=False,
                    use_expectation=True):
    '''
    Build an LP model for the supply chain network InvManagement problem (v2 and v3).
    Three modes exist:
        1) Perfect information (Oracle): Gives the optimal reorder quantities if 
            the demand were known before hand. Set perfect_information=True.
        2) Shrinking horizon: Assumes the average demand from the specified distribution 
            is used. Set window_size=np.Inf
        3) Rolling horizon: Assumes the average demand from the specified distribution 
            is used. Set window_size for the rolling window.

    Note: if a user demand is used, but it is not sampled from a distribution (sample_path = False),
            this is equivalent to having use_expectation = False
    '''

    #adjust window_size towards the end of the simulation (shrinking horizon)
    window_size = min(window_size, env.num_periods - env.period)
    if perfect_information:
        window_size = env.num_periods - env.period

    #create model
    lp = pe.ConcreteModel()

    #define sets
    lp.J = pe.Set(initialize=env.main_nodes)
    lp.Jraw = pe.Set(initialize=env.rawmat)
    lp.Jdistrib = pe.Set(initialize=env.distrib)
    lp.Jretail = pe.Set(initialize=env.retail)
    lp.Jmarket = pe.Set(initialize=env.market)
    lp.Jfactory = pe.Set(initialize=env.factory)
    lp.network_links = pe.Set(dimen=2, initialize=env.network_links)
    lp.reorder_links = pe.Set(dimen=2, initialize=env.reorder_links)
    lp.retail_links = pe.Set(dimen=2, initialize=env.retail_links)
    lp.demands = pe.Set(dimen=3,
                        initialize=[(t, ) + e for e in env.retail_links
                                    for t in range(window_size)])
    lp.T = pe.RangeSet(0, window_size - 1)
    lp.T1 = pe.RangeSet(0, window_size)

    #define parameters
    lp.h = pe.Param(lp.J,
                    initialize={j: env.graph.nodes[j]['h']
                                for j in lp.J
                                })  #inventory holding cost at main nodes
    lp.C = pe.Param(lp.Jfactory,
                    initialize={
                        j: env.graph.nodes[j]['C']
                        for j in lp.Jfactory
                    })  #production capacity at each factory node
    lp.o = pe.Param(lp.Jfactory,
                    initialize={
                        j: env.graph.nodes[j]['o']
                        for j in lp.Jfactory
                    })  #operating cost at each factory node
    lp.v = pe.Param(lp.Jfactory,
                    initialize={
                        j: env.graph.nodes[j]['v']
                        for j in lp.Jfactory
                    })  #production yield at each factory node
    lp.p = pe.Param(lp.network_links,
                    initialize={
                        e: env.graph.edges[e]['p']
                        for e in lp.network_links
                    })  #price for selling/purchasing on a link
    lp.L = pe.Param(lp.reorder_links,
                    initialize={
                        e: env.graph.edges[e]['L']
                        for e in lp.reorder_links
                    })  #price for selling/purchasing on a link
    lp.g = pe.Param(lp.reorder_links,
                    initialize={
                        e: env.graph.edges[e]['g']
                        for e in lp.reorder_links
                    })  #price for selling/purchasing on a link
    lp.b = pe.Param(lp.retail_links,
                    initialize={
                        e: env.graph.edges[e]['b']
                        for e in lp.retail_links
                    })  #price for selling/purchasing on a link
    alpha = env.alpha  #time-valued discount
    backlog = env.backlog  #backlog or lost sales
    #demand profile
    if perfect_information:
        D = {
            e: env.graph.edges[e]['demand_dist'].rvs(
                size=window_size, **env.graph.edges[e]['dist_param'])
            if np.sum(env.graph.edges[e]['user_D']) == 0 else
            env.graph.edges[e]['user_D'][env.period:]
            for e in lp.retail_links
        }  #demands on a retail link for each period
    else:
        D = {
            e: np.ones(window_size) * env.graph.edges[e]['demand_dist'].mean(
                **env.graph.edges[e]['dist_param'])
            if np.sum(env.graph.edges[e]['user_D']) == 0
            or env.graph.edges[e]['sample_path'] else np.ones(window_size) *
            np.mean(env.graph.edges[e]['user_D'])
            for e in lp.retail_links
        }  #demands on a retail link for each period
    lp.D = pe.Param(lp.demands,
                    initialize={te: D[te[1:]][te[0]]
                                for te in lp.demands})  #store demands
    prob = {
        e: env.graph.edges[e]['demand_dist'].pmf(
            D[e], **env.graph.edges[e]['dist_param'])
        if np.sum(env.graph.edges[e]['user_D']) == 0
        or env.graph.edges[e]['sample_path'] else np.ones(window_size)
        for e in lp.retail_links
    }  #probability of each demand based on distribution
    lp.prob = pe.Param(lp.demands,
                       initialize={
                           te: prob[te[1:]][te[0]]
                           for te in lp.demands
                       })  #store probability at each period

    #define variables
    lp.X = pe.Var(lp.T1, lp.J,
                  domain=pe.NonNegativeReals)  #on hand inventory at each node
    lp.Y = pe.Var(lp.T1, lp.reorder_links,
                  domain=pe.NonNegativeReals)  #pipeline inventory on each link
    lp.R = pe.Var(
        lp.T, lp.reorder_links,
        domain=pe.NonNegativeReals)  #reorder quantities for each node
    lp.S = pe.Var(lp.T, lp.network_links,
                  domain=pe.NonNegativeReals)  #sales at each node
    lp.U = pe.Var(lp.T, lp.retail_links,
                  domain=pe.NonNegativeReals)  #unfulfilled sales at each node
    lp.P = pe.Var(lp.T, lp.J, domain=pe.Reals)  #profit at each node

    #initialize on-hand and pipeline inventories
    for j in lp.J:
        lp.X[0, j].fix(env.X.loc[env.period, j])
        for k in env.graph.predecessors(j):
            lp.Y[0, k, j].fix(env.Y.loc[env.period, (k, j)])

    #define constraints
    lp.profit = pe.ConstraintList()
    lp.inv_bal = pe.ConstraintList()
    lp.pip_bal = pe.ConstraintList()
    lp.reorder1 = pe.ConstraintList()
    lp.reorder2 = pe.ConstraintList()
    lp.reorder3 = pe.ConstraintList()
    lp.sales1 = pe.ConstraintList()
    lp.sales2 = pe.ConstraintList()
    lp.sales3 = pe.ConstraintList()
    lp.unfulfilled = pe.ConstraintList()

    #build constraints
    for t in lp.T:
        for j in lp.J:
            #profit
            if j in lp.Jretail:
                lp.profit.add(lp.P[t, j] == alpha**t *
                              (sum(lp.p[j, k] * lp.S[t, j, k]
                                   for k in env.graph.successors(j)) -
                               sum(lp.p[k, j] * lp.R[t, k, j]
                                   for k in env.graph.predecessors(j)) -
                               sum(lp.b[j, k] * lp.U[t, j, k]
                                   for k in env.graph.successors(j)) -
                               lp.h[j] * lp.X[t + 1, j] -
                               sum(lp.g[k, j] * lp.Y[t + 1, k, j]
                                   for k in env.graph.predecessors(j))))
            elif j in lp.Jdistrib:
                lp.profit.add(lp.P[t, j] == alpha**t *
                              (sum(lp.p[j, k] * lp.S[t, j, k]
                                   for k in env.graph.successors(j)) -
                               sum(lp.p[k, j] * lp.R[t, k, j]
                                   for k in env.graph.predecessors(j)) -
                               lp.h[j] * lp.X[t + 1, j] -
                               sum(lp.g[k, j] * lp.Y[t + 1, k, j]
                                   for k in env.graph.predecessors(j))))
            elif j in lp.Jfactory:
                lp.profit.add(
                    lp.P[t, j] == alpha**t *
                    (sum(lp.p[j, k] * lp.S[t, j, k]
                         for k in env.graph.successors(j)) -
                     sum(lp.p[k, j] * lp.R[t, k, j]
                         for k in env.graph.predecessors(j)) - lp.o[j] /
                     lp.v[j] * sum(lp.S[t, j, k]
                                   for k in env.graph.successors(j)) -
                     lp.h[j] * lp.X[t + 1, j] -
                     sum(lp.g[k, j] * lp.Y[t + 1, k, j]
                         for k in env.graph.predecessors(j))))
            #on-hand inventory
            if j in lp.Jdistrib:
                lp.inv_bal.add(lp.X[t + 1, j] == lp.X[t, j] + sum(
                    0 if env.period + t -
                    lp.L[k, j] < 0 else lp.R[t - lp.L[k, j], k, j] if t -
                    lp.L[k, j] >= 0 else env.R.loc[env.period + t - lp.L[k, j],
                                                   (k, j)]
                    for k in env.graph.predecessors(j)) -
                               sum(lp.S[t, j, k]
                                   for k in env.graph.successors(j)))
            else:
                lp.inv_bal.add(
                    lp.X[t + 1, j] == lp.X[t, j] +
                    sum(0 if env.period + t -
                        lp.L[k, j] < 0 else lp.R[t - lp.L[k, j], k, j] if t -
                        lp.L[k, j] >= 0 else env.R.loc[env.period + t -
                                                       lp.L[k, j], (k, j)]
                        for k in env.graph.predecessors(j)) -
                    1 / lp.v[j] * sum(lp.S[t, j, k]
                                      for k in env.graph.successors(j)))
            #pipeline inventory
            for k in env.graph.predecessors(j):
                if env.period + t - lp.L[
                        k,
                        j] < 0:  #if reorder is prior to when the problem started
                    lp.pip_bal.add(lp.Y[t + 1, k,
                                        j] == lp.Y[t, k, j] + lp.R[t, k, j])
                elif t - lp.L[
                        k,
                        j] >= 0:  #if reorder is in the current horizon scope
                    lp.pip_bal.add(lp.Y[t + 1, k, j] == lp.Y[t, k, j] -
                                   lp.R[t - lp.L[k, j], k, j] + lp.R[t, k, j])
                else:  #if reorder is available in history
                    lp.pip_bal.add(lp.Y[t + 1, k, j] == lp.Y[t, k, j] -
                                   env.R.loc[env.period + t - lp.L[k, j],
                                             (k, j)] + lp.R[t, k, j])

            #reorder quantities
            if j in lp.Jdistrib and j not in lp.Jretail:
                lp.reorder1.add(
                    sum(lp.R[t, j, k]
                        for k in env.graph.successors(j)) <= lp.X[t, j])
            elif j in lp.Jfactory:
                lp.reorder2.add(
                    sum(lp.R[t, j, k]
                        for k in env.graph.successors(j)) <= lp.X[t, j] *
                    lp.v[j])
                lp.reorder3.add(
                    sum(lp.R[t, j, k]
                        for k in env.graph.successors(j)) <= lp.C[j])

            #sales quantities
            if j in lp.Jretail:
                lp.sales1.add(
                    sum(lp.S[t, j, k]
                        for k in env.graph.successors(j)) <= lp.X[t, j] +
                    sum(0 if env.period + t - lp.L[k, j] < 0 else lp.R[
                        t - lp.L[k, j], k, j] if t - lp.L[k, j] >= 0 else env.
                        R.loc[env.period + t - lp.L[k, j], (k, j)]
                        for k in env.graph.predecessors(j)))
                for k in env.graph.successors(j):
                    if not backlog or env.period + t - 1 < 0:  #if lost sales or if prevoius period is before the problem started
                        lp.sales2.add(lp.S[t, j, k] <= lp.D[t, j, k])
                    elif t - 1 >= 0:  #if backlog quanity from previous period is known
                        lp.sales2.add(
                            lp.S[t, j, k] <= lp.D[t, j, k] + lp.U[t - 1, j, k])
                    else:  #if backlog quanitty is available in history
                        lp.sales2.add(lp.S[t, j, k] <= lp.D[t, j, k] +
                                      env.U.loc[env.period + t - 1, (j, k)])
            else:
                for k in env.graph.successors(j):
                    lp.sales3.add(lp.S[t, j, k] == lp.R[t, j, k])

            #unfulfilled orders
            if j in lp.Jretail:
                for k in env.graph.successors(j):
                    if not backlog or env.period + t - 1 < 0:
                        lp.unfulfilled.add(lp.U[t, j, k] == lp.D[t, j, k] -
                                           lp.S[t, j, k])
                    elif t - 1 >= 0:
                        lp.unfulfilled.add(lp.U[t, j, k] == lp.D[t, j, k] +
                                           lp.U[t - 1, j, k] - lp.S[t, j, k])
                    else:
                        lp.unfulfilled.add(lp.U[t, j, k] == lp.D[t, j, k] +
                                           env.U.loc[env.period + t - 1,
                                                     (j, k)] - lp.S[t, j, k])

    #objective function: maximize average profit
    if use_expectation:
        lp.obj = pe.Objective(expr=1 / (window_size) * sum(
            prod([lp.prob[t, e[0], e[1]]
                  for e in env.retail_links]) * sum(lp.P[t, j] for j in lp.J)
            for t in lp.T),
                              sense=pe.maximize)
    else:
        lp.obj = pe.Objective(expr=1 / (window_size) * sum(lp.P[t, j]
                                                           for j in lp.J
                                                           for t in lp.T),
                              sense=pe.maximize)

    return lp
Exemplo n.º 25
0
def Concrete_model(Data):
    m = en.ConcreteModel()

    #Sets

    m.Time = en.Set(initialize=Data['Set_declare'][1:], ordered=True)
    m.tm = en.Set(initialize=Data['Set_declare'], ordered=True)

    #Parameters
    m.dt = en.Param(initialize=Data['delta_t'])

    m.PVAC = en.Param(initialize=Data['App_comb'][0])
    m.PVSC = en.Param(initialize=Data['App_comb'][1])
    m.DLS = en.Param(initialize=Data['App_comb'][2])
    m.DPS = en.Param(initialize=Data['App_comb'][3])

    m.retail_price = en.Param(m.Time, initialize=Data['retail_price'])
    m.E_PV = en.Param(m.Time, initialize=Data['E_PV'])
    m.E_demand = en.Param(m.Time, initialize=Data['E_demand'])

    m.export_price = en.Param(m.Time, initialize=Data['Export_price'])
    m.capacity_tariff = en.Param(default=Data['Capacity_tariff'])
    m.Inverter_power = en.Param(initialize=Data['Inv_power'])
    m.Inverter_eff = en.Param(initialize=Data['Inverter_eff'])
    m.Converter_eff = en.Param(initialize=Data['Converter_Efficiency_Batt'])

    m.Max_injection = en.Param(initialize=Data['Max_inj'])
    m.SOC_init = en.Param(initialize=Data['Batt'].SOC_min)
    m.SOC_min = en.Param(initialize=Data['Batt'].SOC_min)
    m.SOC_max = en.Param(initialize=Data['SOC_max'])
    m.Efficiency = en.Param(initialize=Data['Batt'].Efficiency)
    m.Batt_dis_max = en.Param(initialize=-Data['Batt'].P_max_dis)
    m.Batt_char_max = en.Param(initialize=Data['Batt'].P_max_char)

    #Variables
    m.Bool_inj = en.Var(m.Time, within=en.Boolean)
    m.Bool_cons = en.Var(m.Time, within=en.Boolean, initialize=0)
    m.Bool_char = en.Var(m.Time, within=en.Boolean)

    m.Bool_dis = en.Var(m.Time, within=en.Boolean, initialize=0)
    m.E_PV_grid = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_PV_load = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_PV_batt = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_PV_curt = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_grid_load = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_grid_batt = en.Var(m.Time,
                           bounds=(0, m.Batt_char_max * m.dt),
                           initialize=0)

    m.E_loss_Batt = en.Var(m.Time, bounds=(0, None), initialize=0)

    m.E_cons = en.Var(m.Time, bounds=(0, None), initialize=0)

    m.E_char = en.Var(m.Time, bounds=(
        0, m.dt *
        m.Batt_char_max))  #because the power is in C terms thus, per hour
    m.E_dis = en.Var(m.Time, bounds=(
        0, m.dt *
        m.Batt_dis_max))  #because the power is in C terms thus, per hour
    m.P_max_day = en.Var(initialize=0)
    m.SOC = en.Var(m.tm, bounds=(m.SOC_min, m.SOC_max), initialize=m.SOC_min)

    m.E_loss_conv = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_loss_inv = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_loss_inv_PV = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_loss_inv_batt = en.Var(m.Time, bounds=(0, None), initialize=0)
    m.E_loss_inv_grid = en.Var(m.Time, bounds=(0, None), initialize=0)
    #Objective Function

    m.total_cost = en.Objective(rule=Obj_fcn, sense=en.minimize)

    #Constraints
    m.cons_r = en.Constraint(m.Time, rule=Cons_rule)

    m.cons_ch1 = en.Constraint(m.Time, rule=Bool_cons_rule_1)
    m.cons_ch2 = en.Constraint(m.Time, rule=Bool_cons_rule_2)
    m.cons_ch3 = en.Constraint(m.Time, rule=Bool_cons_rule_3)
    m.cons_ch4 = en.Constraint(m.Time, rule=Bool_cons_rule_4)

    m.Batt_char_dis = en.Constraint(m.Time, rule=Batt_char_dis)
    m.Batt_ch1 = en.Constraint(m.Time, rule=Bool_char_rule_1)
    m.Batt_ch2 = en.Constraint(m.Time, rule=Bool_char_rule_2)
    m.Batt_cd3 = en.Constraint(m.Time, rule=Bool_char_rule_3)
    m.Batt_cd4 = en.Constraint(m.Time, rule=Bool_char_rule_4)
    m.Batt_SOC = en.Constraint(m.tm, rule=def_storage_state_rule)
    m.Balance_batt = en.Constraint(m.Time, rule=Balance_Batt_rule)
    m.Balance_PV = en.Constraint(m.Time, rule=Balance_PV_rule)
    m.Balance_load = en.Constraint(m.Time, rule=Balance_load_rule)
    m.E_char_r = en.Constraint(m.Time, rule=E_char_rule)
    m.E_dis_r = en.Constraint(m.Time, rule=E_dis_rule)

    m.Curtailment_r = en.Constraint(m.Time, rule=Curtailment_rule)
    m.Sold = en.Constraint(m.Time, rule=Sold_rule)
    m.Inverter = en.Constraint(m.Time, rule=Inverter_rule)
    m.Converter = en.Constraint(m.Time, rule=Converter_rule)
    m.Inverter_grid = en.Constraint(m.Time, rule=Inverter_grid_rule)
    m.Grid_cons = en.Constraint(m.Time, rule=Grid_cons_rule)
    m.P_max = en.Constraint(m.Time, rule=P_max_rule)
    m.PVSC_const = en.Constraint(m.Time, rule=PVSC_rule)
    m.Batt_losses = en.Constraint(m.Time, rule=Batt_losses_rule)
    m.Conv_losses = en.Constraint(m.Time, rule=Conv_losses_rule)
    m.Inv_losses = en.Constraint(m.Time, rule=Inv_losses_rule)

    m.Inv_losses_PV = en.Constraint(m.Time, rule=Inv_losses_PV_rule)
    m.Inv_losses_batt = en.Constraint(m.Time, rule=Inv_losses_Batt_rule)
    m.Inv_losses_grid = en.Constraint(m.Time, rule=Inv_losses_Grid_rule)
    #m.Batt_max_char=en.Constraint(m.Time,rule=Batt_max_char_rule)
    #m.Batt_max_dis=en.Constraint(m.Time,rule=Batt_max_dis_rule)
    #m.SOC_r=en.Constraint(m.Time,rule=SOC_rule)

    return m
def VLLE_block_rule(block):
    #-----------------------------------SETS-----------------------------------

    # local sets that will only be used in VLE block
    block.COMP_HENRY = pe.Set(initialize=[
        'H2', 'CO', 'CO2', 'H2O', 'C1H4', 'C2H6', 'C3H8', 'C2H4', 'C3H6'
    ])
    block.COMP_WATER = pe.Set(initialize=['H2O'])
    block.COMP_NONHENRY = m.COMP_TOTAL - block.COMP_HENRY - block.COMP_WATER

    #-----------------------------GLOBAL VARIABLES-----------------------------

    # global variables
    # print('\t'*2,'Importing VLE Block......')
    # print('\t'*2,'Using the following parent variable:')
    # print('\t'*2,'-'*36)
    # print('\t'*2,block.parent_block().T.name)
    # print('\t'*2,block.parent_block().P.name)
    # print('\t'*2,block.parent_block().x.name)
    # print('\t'*2,block.parent_block().y.name)
    # print('\t'*2,block.parent_block().f_L.name)
    # print('\t'*2,block.parent_block().f_V.name)
    # print('\t'*2,'-'*36)
    # print('')

    #-----------------------------VARIABLES Bounds------------------------------
    def Hen_bounds(model, i):
        lower = min(VLE_bounds['Hen[{}]'.format(i)])
        lower = lower - abs(lower) * 0.2
        upper = max(VLE_bounds['Hen[{}]'.format(i)])
        upper = upper + abs(upper) * 0.2
        return (lower, upper)

    def Hen0_bounds(model, i):
        lower = min(VLE_bounds['Hen0[{}]'.format(i)])
        lower = lower - abs(lower) * 0.2
        upper = max(VLE_bounds['Hen0[{}]'.format(i)])
        upper = upper + abs(upper) * 0.2
        return (lower, upper)

    def gamma_bounds(model, i):
        lower = min(VLE_bounds['gamma[{}]'.format(i)])
        lower = lower - abs(lower) * 0.2
        upper = max(VLE_bounds['gamma[{}]'.format(i)])
        upper = upper + abs(upper) * 0.2
        return (lower, upper)

    def P_sat_bounds(model, i):
        lower = min(VLE_bounds['P_sat[{}]'.format(i)])
        lower = lower - abs(lower) * 0.2
        upper = max(VLE_bounds['P_sat[{}]'.format(i)])
        upper = upper + abs(upper) * 0.2
        return (lower, upper)

    def P_sat_Y_bounds(model, i):
        lower = min(VLE_bounds['P_sat_Y[{}]'.format(i)])
        lower = lower - abs(lower) * 0.2
        upper = max(VLE_bounds['P_sat_Y[{}]'.format(i)])
        upper = upper + abs(upper) * 0.2
        return (lower, upper)

    def P_sat_dY_inf_bounds(model):
        lower = min(VLE_bounds['P_sat_dY_inf'])
        lower = lower - abs(lower) * 0.2
        upper = max(VLE_bounds['P_sat_dY_inf'])
        upper = upper + abs(upper) * 0.2
        return (lower, upper)

    def P_sat_dY0_bounds(model):
        lower = min(VLE_bounds['P_sat_dY0'])
        lower = lower - abs(lower) * 0.2
        upper = max(VLE_bounds['P_sat_dY0'])
        upper = upper + abs(upper) * 0.2
        return (lower, upper)

    def Hen_ref_bounds(model):
        lower = min(VLE_bounds['Hen_ref'])
        lower = lower - abs(lower) * 1
        upper = max(VLE_bounds['Hen_ref'])
        upper = upper + abs(upper) * 1
        return (lower, upper)

    def Hen0_ref_bounds(model):
        lower = min(VLE_bounds['Hen0_ref'])
        lower = lower - abs(lower) * 1
        upper = max(VLE_bounds['Hen0_ref'])
        upper = upper + abs(upper) * 1
        return (lower, upper)

    def gamma_ref_bounds(model):
        lower = min(VLE_bounds['gamma_ref'])
        lower = lower - abs(lower) * 1
        upper = max(VLE_bounds['gamma_ref'])
        upper = upper + abs(upper) * 1
        return (lower, upper)

    def V_L_bounds(model, i):
        lower = min(VLE_bounds['V_L[{}]'.format(i)])
        lower = lower - abs(lower) * 0.1
        upper = max(VLE_bounds['V_L[{}]'.format(i)])
        upper = upper + abs(upper) * 0.1
        return (lower, upper)

    def V_L_dY_inf_bounds(model):
        lower = min(VLE_bounds['V_L_dY_inf'])
        lower = lower - abs(lower) * 1
        upper = max(VLE_bounds['V_L_dY_inf'])
        upper = upper + abs(upper) * 1
        return (lower, upper)

    def V_L_dY0_bounds(model):
        lower = min(VLE_bounds['V_L_dY0'])
        lower = lower - abs(lower) * 1
        upper = max(VLE_bounds['V_L_dY0'])
        upper = upper + abs(upper) * 1
        return (lower, upper)

    def poynting_bounds(model, i):
        lower = min(VLE_bounds['poynting[{}]'.format(i)])
        lower = lower - abs(lower) * 0.1
        upper = max(VLE_bounds['poynting[{}]'.format(i)])
        upper = upper + abs(upper) * 0.1
        return (lower, upper)

    #------------------------------LOCAL VARIABLES------------------------------

    # teared n_ave, initial guess try to converge to calculated average
    block.n_ave = pe.Var(within=pe.NonNegativeReals, bounds=(None, 58))
    block.n_ave_cal = pe.Var(within=pe.NonNegativeReals)

    # fugacity variable
    block.Hen = pe.Var(block.COMP_HENRY,
                       within=pe.NonNegativeReals,
                       bounds=Hen_bounds)  # Bar
    block.Hen0 = pe.Var(block.COMP_HENRY,
                        within=pe.Reals,
                        initialize=4,
                        bounds=Hen0_bounds)
    block.gamma = pe.Var(block.COMP_NONHENRY,
                         within=pe.NonNegativeReals,
                         initialize=0.1,
                         bounds=gamma_bounds)
    block.P_sat = pe.Var(block.COMP_NONHENRY,
                         within=pe.NonNegativeReals,
                         initialize=1e-13,
                         bounds=P_sat_bounds)  # Bar
    block.P_sat_Y = pe.Var(block.COMP_NONHENRY,
                           within=pe.Reals,
                           bounds=P_sat_Y_bounds)
    block.P_sat_dY_inf = pe.Var(within=pe.Reals, bounds=P_sat_dY_inf_bounds)
    block.P_sat_dY0 = pe.Var(within=pe.Reals, bounds=P_sat_dY0_bounds)

    # block.Hen_ref = pe.Var(within=pe.NonNegativeReals,initialize=0.1, bounds=Hen_ref_bounds)
    # block.Hen0_ref = pe.Var(within=pe.Reals,initialize=-1.2, bounds=Hen0_ref_bounds)
    # block.gamma_ref = pe.Var(within=pe.NonNegativeReals,initialize=0.3, bounds=gamma_ref_bounds)

    block.Hen_ref = pe.Var(within=pe.NonNegativeReals, initialize=0.1)
    block.Hen0_ref = pe.Var(within=pe.Reals, initialize=-1.2)
    block.gamma_ref = pe.Var(within=pe.NonNegativeReals, initialize=0.3)

    # molar volume variable
    block.V_L = pe.Var(block.COMP_HENRY | block.COMP_NONHENRY,
                       within=pe.Reals)  #,bounds=V_L_bounds) # cm3/mole
    block.V_L_dY_inf = pe.Var(within=pe.Reals, bounds=V_L_dY_inf_bounds)
    block.V_L_dY0 = pe.Var(within=pe.Reals, bounds=V_L_dY0_bounds)

    # poynting facotor variable
    block.poynting = pe.Var(block.COMP_HENRY | block.COMP_NONHENRY,
                            within=pe.Reals,
                            bounds=poynting_bounds)

    # initialize these variable: 1/2(ub+lb)
    for i in block.COMP_HENRY:
        block.Hen[i] = mean(VLE_bounds['Hen[{}]'.format(i)])
        block.Hen0[i] = mean(VLE_bounds['Hen0[{}]'.format(i)])

    for i in block.COMP_NONHENRY:
        block.gamma[i] = mean(VLE_bounds['gamma[{}]'.format(i)])
        block.P_sat[i] = mean(VLE_bounds['P_sat[{}]'.format(i)])
        block.P_sat_Y[i] = mean(VLE_bounds['P_sat_Y[{}]'.format(i)])
    #
    block.P_sat_dY_inf = mean(VLE_bounds['P_sat_dY_inf'])
    block.P_sat_dY0 = mean(VLE_bounds['P_sat_dY0'])
    block.V_L_dY_inf = mean(VLE_bounds['V_L_dY_inf'])
    block.V_L_dY0 = mean(VLE_bounds['V_L_dY0'])

    # block.Hen_ref = mean(VLE_bounds['Hen_ref'])
    # block.Hen0_ref = mean(VLE_bounds['Hen0_ref'])
    # block.gamma_ref = mean(VLE_bounds['gamma_ref'])

    print('>', 'Importing VLE Blocks......')
    print('>', 'Adding the following local variable:')
    print('-' * 50)

    for i in block.component_objects(pe.Var, active=True):
        print('|', i)

    print('-' * 50)
    print('')

    #---------------------------------Equations---------------------------------

    # henry component
    def f_L_HENRY_rule(block, i):
        return block.parent_block(
        ).f_L[i] == block.Hen[i] * block.parent_block().x[i]

    block.f_L_HENRY_con = pe.Constraint(block.COMP_HENRY, rule=f_L_HENRY_rule)

    # henry's constant
    def Hen_rule(block, i):
        return block.Hen[i] * pe.exp(block.n_ave * e.henry.dHen[i]) == pe.exp(
            block.Hen0[i])

    block.Hen_con = pe.Constraint(block.COMP_HENRY, rule=Hen_rule)

    def Hen0_rule(block, i):
        return block.Hen0[i] == e.henry.A[i] + e.henry.B[i]/block.parent_block().T + e.henry.C[i]*pe.log(block.parent_block().T) + \
                    e.henry.D[i]*(block.parent_block().T**2) + e.henry.E[i]/(block.parent_block().T**2)

    block.Hen0_con = pe.Constraint(block.COMP_HENRY, rule=Hen0_rule)

    def Hen_ref_rule(block):
        return block.Hen_ref * pe.exp(
            block.n_ave * e.henry.dHen['C6H14']) == pe.exp(block.Hen0_ref)

    block.Hen_ref_con = pe.Constraint(rule=Hen_ref_rule)

    def Hen0_ref_rule(block):
        return block.Hen0_ref == e.henry.A['C6H14'] + e.henry.B['C6H14']/block.parent_block().T + e.henry.C['C6H14']*pe.log(block.parent_block().T) + \
                    e.henry.D['C6H14']*(block.parent_block().T**2) + e.henry.E['C6H14']/(block.parent_block().T**2)

    block.Hen0_ref_con = pe.Constraint(rule=Hen0_ref_rule)

    # non-henry component
    def f_L_NONHENRY_rule(block, i):
        return block.parent_block(
        ).f_L[i] == block.gamma[i] * block.P_sat[i] * block.parent_block().x[i]

    block.f_L_NONHENRY_con = pe.Constraint(block.COMP_NONHENRY,
                                           rule=f_L_NONHENRY_rule)

    # acticity coefficient gamma
    def gamma_rule(block, i):
        return pe.log(block.gamma[i])*(block.n_ave - cal_cnumber('C6H14')) == \
                pe.log(block.gamma_ref)*(block.n_ave - cal_cnumber(i))

    block.gamma_con = pe.Constraint(block.COMP_NONHENRY, rule=gamma_rule)

    def gamma_ref_rule(block):
        return block.gamma_ref * block.P_sat['C6H14'] == block.Hen_ref

    block.gamma_ref_con = pe.Constraint(rule=gamma_ref_rule)

    def n_ave_rule(block):
        return block.n_ave_cal == sum(block.parent_block().x[i]*cal_cnumber(i) for i in m.COMP_PARAFFIN | \
                m.COMP_OLEFIN)/(1-sum(block.parent_block().x[i] for i in m.COMP_INORG))

    block.n_ave_con = pe.Constraint(rule=n_ave_rule)

    # saturated pressure
    def P_sat_rule1(block, i):
        if i in m.COMP_PARAFFIN:
            n_n0 = cal_cnumber(i) - e.nonhenry.n0_paraffin
        elif i in m.COMP_OLEFIN:
            n_n0 = cal_cnumber(i) - e.nonhenry.n0_olefin
        return block.P_sat_Y[i] == e.nonhenry.Y_inf_0 + block.P_sat_dY_inf*(n_n0) \
                    - block.P_sat_dY0*pe.exp(-e.nonhenry.beta*(n_n0)**e.nonhenry.gamma)

    block.P_sat_con = pe.Constraint(block.COMP_NONHENRY, rule=P_sat_rule1)

    def P_sat_rule2(block, i):
        return block.P_sat[i] == pe.exp(block.P_sat_Y[i])

    block.P_sat_con2 = pe.Constraint(block.COMP_NONHENRY, rule=P_sat_rule2)

    def P_sat_dY_inf_rule(block):
        return e.nonhenry.dY_inf.A + e.nonhenry.dY_inf.B/block.parent_block().T + e.nonhenry.dY_inf.C*pe.log(block.parent_block().T) + \
                e.nonhenry.dY_inf.D*(block.parent_block().T)**2 + e.nonhenry.dY_inf.E/(block.parent_block().T)**2 == block.P_sat_dY_inf

    block.P_sat_dY_inf_con = pe.Constraint(rule=P_sat_dY_inf_rule)

    def P_sat_dY0_rule(block):
        return e.nonhenry.dY0.A + e.nonhenry.dY0.B/block.parent_block().T + e.nonhenry.dY0.C*pe.log(block.parent_block().T) + \
                e.nonhenry.dY0.D*(block.parent_block().T)**2 + e.nonhenry.dY0.E/(block.parent_block().T)**2 == block.P_sat_dY0

    block.P_sat_dY0_con = pe.Constraint(rule=P_sat_dY0_rule)

    # gas phase assume ideal
    def f_V_rule(block, i):
        return block.parent_block().P * block.parent_block(
        ).y[i] == block.parent_block().f_V[i]

    block.f_V_con = pe.Constraint(block.COMP_HENRY | block.COMP_NONHENRY,
                                  rule=f_V_rule)

    # molar volume Equation
    def V_L_nonHen_rule(block, i):
        if i in m.COMP_PARAFFIN:
            n_n0 = cal_cnumber(i) - e.V_L_nonhenry.n0_paraffin
            n_n0_ = cal_cnumber(i) + e.V_L_nonhenry.n0_paraffin
        elif i in m.COMP_OLEFIN:
            n_n0 = cal_cnumber(i) - e.V_L_nonhenry.n0_olefin
            n_n0_ = cal_cnumber(i) + e.V_L_nonhenry.n0_olefin
        return block.V_L[i] == e.V_L_nonhenry.Y_inf_0 + block.V_L_dY_inf*(n_n0) \
                    - block.V_L_dY0*pe.exp(-e.V_L_nonhenry.beta*(n_n0_)**e.V_L_nonhenry.gamma)

    block.V_L_nonHen_con = pe.Constraint(block.COMP_NONHENRY
                                         | {'C3H8', 'C3H6'},
                                         rule=V_L_nonHen_rule)

    def V_L_dY_inf_rule(block):
        return e.V_L_nonhenry.dY_inf.A + e.V_L_nonhenry.dY_inf.B*block.parent_block().T + e.V_L_nonhenry.dY_inf.C*(block.parent_block().T)**2 + \
                e.V_L_nonhenry.dY_inf.D*(block.parent_block().T)**3 == block.V_L_dY_inf

    block.V_L_dY_inf_con = pe.Constraint(rule=V_L_dY_inf_rule)

    def V_L_dY0_rule(block):
        return e.V_L_nonhenry.dY0.A + e.V_L_nonhenry.dY0.B*block.parent_block().T + e.V_L_nonhenry.dY0.C*(block.parent_block().T)**2 + \
                e.V_L_nonhenry.dY0.D*(block.parent_block().T)**3 == block.V_L_dY0

    block.V_L_dY0_con = pe.Constraint(rule=V_L_dY0_rule)

    def V_L_Hen_rule(block, i):
        return block.V_L[i] == e.V_L_henry.A[i] + e.V_L_henry.B[
            i] * block.parent_block().T + block.n_ave * e.V_L_henry.dV[i]

    block.V_L_Hen_con = pe.Constraint(block.COMP_HENRY - {'C3H8', 'C3H6'},
                                      rule=V_L_Hen_rule)

    # poynting factor equation
    def poynting_rule(block, i):
        return block.poynting[i] == pe.exp(0.1 * block.V_L[i] *
                                           (block.parent_block().P) /
                                           (e.R * block.parent_block().T))

    block.poynting_con = pe.Constraint(block.COMP_HENRY | block.COMP_NONHENRY,
                                       rule=poynting_rule)
Exemplo n.º 27
0
def create_lineal_model_tardiness( model, TP ):
    
    ## Número de trabajo y máquinas
    num_trabajos = len(TP)
    num_maquinas = len(TP[0])
    jobs = [i+1 for i in range(num_trabajos)]
    machines = [i+1 for i in range(num_maquinas)]
    
    ## --------------------- CONJUNTOS ----------------------------
    model.J = pyo.Set( initialize = jobs ) 
    model.M = pyo.Set( initialize = machines )
    model.P = pyo.Set( initialize = jobs )
    
    ## ## ---------------------- PARÁMETROS ----------------------------
    def paramTP(model, j, m):
        return(TP[j-1][m-1])
    
    model.T_Proc = pyo.Param(model.J,model.M, initialize = paramTP)
    
    ## ---------------------- VARIABLES ----------------------------
    model.x = pyo.Var(model.J, model.P, domain = pyo.Binary)
    model.T_Inicio = pyo.Var(model.P, model.M)
    model.T_Final = pyo.Var(model.P, model.M)
    model.Makespan = pyo.Var()
    
    ## ---------------------- FUNCIÓN OBJETIVO ----------------------------
    def ObjFunc( model ):
        return model.Makespan
    
    model.FO = pyo.Objective( rule = ObjFunc )
    
    ## ---------------------- RESTRICCIONES ----------------------------
    def r1( model, j ):
        return sum( model.x[j,p] for p in model.P ) == 1
    
    model.r1 = pyo.Constraint( model.J, rule = r1 )
    
    def r2( model, p ):
        return sum( model.x[j,p] for j in model.J ) == 1
    
    model.r2 = pyo.Constraint( model.P, rule = r2 )
    
    def r3( model, p, m ):
        return model.T_Final[p,m] == model.T_Inicio[p,m] + sum( model.x[j,p]*model.T_Proc[j,m] for j in model.J )
    
    model.r3 = pyo.Constraint( model.P, model.M, rule = r3 )
    
    def r4( model, p, m ):
        if ( m > 1 ):
            return model.T_Inicio[p,m] == model.T_Final[p,m-1]
        return pyo.Constraint.Skip
    
    model.r4 = pyo.Constraint( model.P, model.M, rule = r4 )
    
    def r5( model, p, m ):
        if ( p > 1 ):
            return model.T_Inicio[p,m] >= model.T_Final[p-1,m]
        return pyo.Constraint.Skip
    
    model.r5 = pyo.Constraint( model.P, model.M, rule = r5 )
    
    def r6( model ):
        return model.T_Inicio[1,1] == 0
    
    model.r6 = pyo.Constraint( rule = r6 )
    
    def r7( model ):
        return model.Makespan == model.T_Final[len(model.J), len(model.M)]
    
    model.r7 = pyo.Constraint( rule = r7 )
Exemplo n.º 28
0
"""
Seccion (1) Definiciones basicas
Conjuntos: Fases / Condiciones de aplicacion
Parameteros: Densidad/ viscosidad nw / costo
Variables: Fraccion masica / shear rate / viscosidad 
Restricciones: Balance de masa
"""

# Nuevo modelo
datafile = 'basico.dat' 

m = pe.AbstractModel()  # Modelo de optimizacion

# Conjuntos
m.I = pe.Set(initialize = ['Wat', 'Oil', 'Thick', 'Surf'])  # Fases separadas
m.Pr = pe.Set(initialize = ['appli', 'mix'])                # Condiciones de proceso  

# Parametros
m.rho = pe.Param(m.I, default=0)   # Densidad [kg/m3]
m.dymu = pe.Param(m.I, default=0)  # Viscosidad dinamica [Pa.s]
m.cost = pe.Param(m.I, default=0)  # Costo unitario [$/kg]

m = m.create_instance(datafile)    # Creacion objeto modelo 

# Variables
def sr_bounds(m, i):  # Regla de limites de shear rate
    if i == 'appli':
        return (100, 100)
    else:
        return (100, 1200)
Exemplo n.º 29
0
    def solve(self, solver='cbc', network=True, commit=True, outdir='results'):

        #Define the Model
        m = pe.ConcreteModel()

        #Define the Sets
        m.g = pe.Set(initialize=list(range(self.ng)), ordered=True)
        m.l = pe.Set(initialize=list(range(self.nl)), ordered=True)
        m.b = pe.Set(initialize=list(range(self.nb)), ordered=True)
        m.t = pe.Set(initialize=list(range(self.nt)), ordered=True)

        #Define Variables

        #Objective Function
        m.z = pe.Var()

        #Active and Reactive Power Generations
        m.pgg = pe.Var(m.g, m.t, within=pe.NonNegativeReals)
        m.qgg = pe.Var(m.g, m.t, within=pe.Reals)

        #Demand and Renewable Shedding
        m.pds = pe.Var(m.b, m.t, within=pe.Binary)
        m.prs = pe.Var(m.b, m.t, within=pe.NonNegativeReals)

        #Voltage Magnitude
        m.vol = pe.Var(m.b,
                       m.t,
                       within=pe.Reals,
                       bounds=(self.vmin, self.vmax))

        #Active and Reactive Line Flows
        m.pll = pe.Var(m.l, m.t, within=pe.Reals)  #Active Power
        m.qll = pe.Var(m.l, m.t, within=pe.Reals)  #Reactive Power

        if commit:
            m.u = pe.Var(m.g, m.t, within=pe.Binary)
        else:
            m.u = pe.Var(m.g, m.t, within=pe.NonNegativeReals, bounds=(0, 1))

        #Objective Function
        def obj_rule(m):
            return m.z

        m.obj = pe.Objective(rule=obj_rule)

        #Definition Cost
        def cost_def_rule(m):
            if commit:
                return m.z == sum(
                    self.gen['start'][g] * m.u[g, t] for g in m.g
                    for t in m.t) - sum(
                        self.gen['start'][g] * m.u[g, t - 1] for g in m.g
                        for t in m.t if t > 1) + self.sb * (
                            sum(self.gen['cost'][g] * m.pgg[g, t] for g in m.g
                                for t in m.t) +
                            sum(self.cds * self.pde.iloc[t, b] * m.pds[b, t]
                                for b in m.b
                                for t in m.t) + sum(self.crs * m.prs[b, t]
                                                    for b in m.b for t in m.t))
            else:
                return m.z == self.sb * (
                    sum(self.gen['cost'][g] * m.pgg[g, t] for g in m.g
                        for t in m.t) +
                    sum(self.cds * self.pde.iloc[t, b] * m.pds[b, t]
                        for b in m.b for t in m.t) + sum(self.crs * m.prs[b, t]
                                                         for b in m.b
                                                         for t in m.t))

        m.cost_def = pe.Constraint(rule=cost_def_rule)

        #Active Energy Balance
        def act_bal_rule(m, b, t):
            return sum(m.pgg[g, t] for g in m.g
                       if self.gen['bus'][g] == b) + self.pre.iloc[t, b] + sum(
                           m.pll[l, t] for l in m.l
                           if self.lin['to'][l] == b) == self.pde.iloc[
                               t, b] * (1 - m.pds[b, t]) + m.prs[b, t] + sum(
                                   m.pll[l, t]
                                   for l in m.l if self.lin['from'][l] == b)

        m.act_bal = pe.Constraint(m.b, m.t, rule=act_bal_rule)

        #Reactive Energy Balance
        def rea_bal_rule(m, b, t):
            return sum(m.qgg[g, t]
                       for g in m.g if self.gen['bus'][g] == b) + sum(
                           m.qll[l, t] for l in m.l if self.lin['to'][l] ==
                           b) == self.qde.iloc[t, b] * (1 - m.pds[b, t]) + sum(
                               m.qll[l, t]
                               for l in m.l if self.lin['from'][l] == b)

        m.rea_bal = pe.Constraint(m.b, m.t, rule=rea_bal_rule)

        #Minimum Active Generation
        def min_act_gen_rule(m, g, t):
            return m.pgg[g, t] >= m.u[g, t] * self.gen['pmin'][g]

        m.min_act_gen = pe.Constraint(m.g, m.t, rule=min_act_gen_rule)

        #Maximum Active Generation
        def max_act_gen_rule(m, g, t):
            return m.pgg[g, t] <= m.u[g, t] * self.gen['pmax'][g]

        m.max_act_gen = pe.Constraint(m.g, m.t, rule=max_act_gen_rule)

        #Minimum Reactive Generation
        def min_rea_gen_rule(m, g, t):
            return m.qgg[g, t] >= m.u[g, t] * self.gen['qmin'][g]

        m.min_rea_gen = pe.Constraint(m.g, m.t, rule=min_rea_gen_rule)

        #Maximum Reactive Generation
        def max_rea_gen_rule(m, g, t):
            return m.qgg[g, t] <= m.u[g, t] * self.gen['qmax'][g]

        m.max_rea_gen = pe.Constraint(m.g, m.t, rule=max_rea_gen_rule)

        #Maximum Renewable Shedding
        def max_shed_rule(m, b, t):
            return m.prs[b, t] <= self.pre.iloc[t, b]

        m.max_shed = pe.Constraint(m.b, m.t, rule=max_shed_rule)

        #Line flow Definition
        def flow_rule(m, l, t):
            if network:
                return (
                    m.vol[self.lin['from'][l], t] -
                    m.vol[self.lin['to'][l], t]) == self.lin['res'][l] * m.pll[
                        l, t] + self.lin['rea'][l] * m.qll[l, t]
            else:
                return pe.Constraint.Skip

        m.flow = pe.Constraint(m.l, m.t, rule=flow_rule)

        #Max Active Line Flow
        def max_act_flow_rule(m, l, t):
            if network:
                return m.pll[l, t] <= self.lin['pmax'][l]
            else:
                return pe.Constraint.Skip

        m.max_act_flow = pe.Constraint(m.l, m.t, rule=max_act_flow_rule)

        #Min Active Line Flow
        def min_act_flow_rule(m, l, t):
            if network:
                return m.pll[l, t] >= -self.lin['pmax'][l]
            else:
                return pe.Constraint.Skip

        m.min_act_flow = pe.Constraint(m.l, m.t, rule=min_act_flow_rule)

        #Max Reactive Line Flow
        def max_rea_flow_rule(m, l, t):
            if network:
                return m.qll[l, t] <= self.lin['qmax'][l]
            else:
                return pe.Constraint.Skip

        m.max_rea_flow = pe.Constraint(m.l, m.t, rule=max_rea_flow_rule)

        #Min Reactive Line Flow
        def min_rea_flow_rule(m, l, t):
            if network:
                return m.qll[l, t] >= -self.lin['qmax'][l]
            else:
                return pe.Constraint.Skip

        m.min_rea_flow = pe.Constraint(m.l, m.t, rule=min_rea_flow_rule)

        #Voltage Magnitude at Reference Bus
        def vol_ref_rule(m, t):
            if network:
                return sum(m.vol[b, t] for b in m.b if b == 0) == 1
            else:
                return pe.Constraint.Skip

        m.vol_ref = pe.Constraint(m.t, rule=vol_ref_rule)

        #Solve the optimization problem
        solver_manager = pe.SolverManagerFactory('neos')
        opt = pe.SolverFactory(solver)
        opt.options['threads'] = 1
        opt.options['mipgap'] = 1e-9
        result = solver_manager.solve(m,
                                      opt=opt,
                                      symbolic_solver_labels=True,
                                      tee=True)
        print(result['Solver'][0])
        print(m.display())
        #Save the results
        self.output = m

        self.u_output = pyomo2df(m.u, m.g, m.t).T

        self.pgg_output = pyomo2df(m.pgg, m.g, m.t).T
        self.qgg_output = pyomo2df(m.qgg, m.g, m.t).T

        self.pds_output = pyomo2df(m.pds, m.b, m.t).T
        self.prs_output = pyomo2df(m.prs, m.b, m.t).T

        self.vol_output = pyomo2df(m.vol, m.b, m.t).T

        self.pll_output = pyomo2df(m.pll, m.l, m.t).T
        self.qll_output = pyomo2df(m.qll, m.l, m.t).T

        # Check if output folder exists
        if not os.path.exists(outdir):
            os.makedirs(outdir)

        self.u_output.to_csv(outdir + os.sep + 'u.csv', index=False)

        self.pgg_output.to_csv(outdir + os.sep + 'pg.csv', index=False)
        self.qgg_output.to_csv(outdir + os.sep + 'qg.csv', index=False)

        self.pds_output.to_csv(outdir + os.sep + 'pds.csv', index=False)
        self.prs_output.to_csv(outdir + os.sep + 'prs.csv', index=False)

        self.vol_output.to_csv(outdir + os.sep + 'vol.csv', index=False)

        self.pll_output.to_csv(outdir + os.sep + 'pl.csv', index=False)
        self.qll_output.to_csv(outdir + os.sep + 'ql.csv', index=False)
Exemplo n.º 30
0
def test_detailed_battery_dispatch(site):
    expected_objective = 37003.621
    expected_lifecycles =  0.331693
    # TODO: McCormick error is large enough to make objective 50% higher than
    #  the value of simple battery dispatch objective

    dispatch_n_look_ahead = 48

    battery = Battery(site, technologies['battery'])

    model = pyomo.ConcreteModel(name='detailed_battery_only')
    model.forecast_horizon = pyomo.Set(initialize=range(dispatch_n_look_ahead))
    battery._dispatch = ConvexLinearVoltageBatteryDispatch(model,
                                                           model.forecast_horizon,
                                                           battery._system_model,
                                                           battery._financial_model)

    # Manually creating objective for testing
    prices = {}
    block_length = 8
    index = 0
    for i in range(int(dispatch_n_look_ahead / block_length)):
        for j in range(block_length):
            if i % 2 == 0:
                prices[index] = 30.0  # assuming low prices
            else:
                prices[index] = 100.0  # assuming high prices
            index += 1

    model.price = pyomo.Param(model.forecast_horizon,
                              within=pyomo.Reals,
                              initialize=prices,
                              mutable=True,
                              units=u.USD / u.MWh)

    def create_test_objective_rule(m):
        return (sum((m.convex_LV_battery[t].time_duration * (
                (m.price[t] - m.convex_LV_battery[t].cost_per_discharge) * m.convex_LV_battery[t].discharge_power
                - (m.price[t] + m.convex_LV_battery[t].cost_per_charge) * m.convex_LV_battery[t].charge_power))
                   for t in m.convex_LV_battery.index_set())
                - m.lifecycle_cost * m.lifecycles)

    model.test_objective = pyomo.Objective(
        rule=create_test_objective_rule,
        sense=pyomo.maximize)

    battery.dispatch.initialize_parameters()
    battery.dispatch.update_time_series_parameters(0)
    model.initial_SOC = battery.dispatch.minimum_soc   # Set initial SOC to minimum
    assert_units_consistent(model)

    results = HybridDispatchBuilderSolver.glpk_solve_call(model)
    # TODO: trying to solve the nonlinear problem but solver doesn't work...
    #           Need to try another nonlinear solver
    # results = HybridDispatchBuilderSolver.mindtpy_solve_call(model)

    assert results.solver.termination_condition == TerminationCondition.optimal
    assert pyomo.value(model.test_objective) == pytest.approx(expected_objective, 1e-3)
    assert pyomo.value(battery.dispatch.lifecycles) == pytest.approx(expected_lifecycles, 1e-3)
    assert sum(battery.dispatch.charge_power) > 0.0
    assert sum(battery.dispatch.discharge_power) > 0.0
    assert sum(battery.dispatch.charge_current) >= sum(battery.dispatch.discharge_current) - 1e-7