예제 #1
0
 def powerflowreact(model, i):
     if i in gb:
         return model.Qg[i]-Qd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) *
                                         sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb))
     else:
         return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * sin(model.va[i] - model.va[j] -
                                                               ang(y[i, j])) for j in range(nb)) == -Qd[i]
예제 #2
0
 def powerflowact(model, i):
     if i in gb:
         return model.Pg[i]-Pd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) *
                                         cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb))
     else:
         return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * cos(model.va[i] - model.va[j] -
                                                               ang(y[i, j])) for j in range(nb)) == -Pd[i]
예제 #3
0
 def qto(model, i):
     if i in tp:
         return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \
                               model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / model.tr[i] * \
                               sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
     else:
         return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \
                               model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / tr0[i] * \
                               sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
예제 #4
0
 def pto(model, i):
     if i in tp:
         return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \
                               model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / model.tr[i] * \
                               cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
     else:
         return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \
                               model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) / tr0[i] * \
                               cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
예제 #5
0
def test_model_mfcc(model, input_path, output_path, neighbor, nffts, normal_flag=0):
    _, s = wavfile.read(input_path)
    _, _, Zxx = stft(s, freq)
    Zxx1 = log((abss(Zxx)).T+1e-7)
    y_input = combine_with_mfcc(input_path, neighbor=neighbor, nfft=nffts, normal_flag=normal_flag)
    y = model.predict(y_input)
    y = (np.delete(y, np.s_[-39:], axis=1)).T   # delete mfcc data
    ypreComplex = exp(y) * exp(complex(0, 1) * ang(Zxx)) if normal_flag == 0 \
        else exp(unnormalize(y, Zxx1)) * exp(complex(0, 1) * ang(Zxx))
    # ypreComplex = unnormalize(exp(y) * exp(complex(0, 1) * ang(Zxx)), abss(Zxx))  # wrong code
    _, xrec = istft(ypreComplex, freq)
    dataWrite = xrec.astype(np.int16)
    wavfile.write(output_path, freq, dataWrite)
예제 #6
0
def test_model(model, input_path, output_path, neighbor, nffts, normal_flag=0):
    _, s = wavfile.read(input_path)
    _, _, Zxx = stft(s, freq)
    Zxx1 = log((abss(Zxx)).T+1e-7)
    y_input = make_window_buffer(input_path, neighbor=neighbor, nfft=nffts, normal_flag=normal_flag)
    y = model.predict(y_input).T
    # print(y.shape, unnormalize(y, abss(Zxx)).shape, unnormalize(y, abss(Zxx)).dtype)
    ypreComplex = exp(y) * exp(complex(0, 1) * ang(Zxx)) if normal_flag == 0 \
        else exp(unnormalize(y, Zxx1)) * exp(complex(0, 1) * ang(Zxx))
    # ypreComplex = unnormalize(exp(y) * exp(complex(0, 1) * ang(Zxx)), abss(Zxx))  # wrong code
    _, xrec = istft(ypreComplex, freq)
    dataWrite = xrec.astype(np.int16)
    wavfile.write(output_path, freq, dataWrite)
예제 #7
0
def test_GRU(model, input_path, output_path):
    _, s = wavfile.read(input_path)
    _, _, Zxx = stft(s, freq)
    Zxx1 = log((abss(Zxx)).T + 1e-7)
    print(Zxx1.shape)
    yt = pack_GRU(input_path)
    y = model.predict(np.reshape(yt, [1, -1, 22]))
    y = unpack_GRU(y)
    print(y.shape)
    ypreComplex = exp(y.T * Zxx1.T) * exp(complex(0, 1) * ang(Zxx))
    _, xrec = istft(ypreComplex, freq)
    dataWrite = xrec.astype(np.int16)
    wavfile.write(output_path, freq, dataWrite)
예제 #8
0
 def powerflowreact(model, i):
     bfrom_i = tp[find(fr[tp] == i)]  # branches from bus i with transformer
     bto_i = tp[find(to[tp] == i)]  # branches to bus i with transformer
     allbut_i = find(bus[:, BUS_I] != i)  # Set of other buses
     sh = sd[find(sd == i)]  # Detect shunt elements
     if i in gb:
         return model.Qg[i]-Qd[i] == \
                sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                    sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * sin(model.va[i] - model.va[to[j]] - ang(yk[j]))
                    * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * sin(model.va[i] - model.va[fr[j]] - ang(yk[j]))
                    * (1 / model.tr[j] - 1) for j in bto_i) + \
                model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j] ** 2 - 1) * np.sin(- ang(yk[j]))
                                        for j in bfrom_i) - imag(y[i, i]) - sum(model.Bs[j] for j in sh))
     else:
         return sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                    sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * sin(model.va[i] -
                    model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * sin(model.va[i] -
                    model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j] ** 2 - 1) * np.sin(- ang(yk[j]))
                                        for j in bfrom_i) - imag(y[i, i]) - sum(model.Bs[j] for j in sh)) == - Qd[i]
예제 #9
0
 def powerflowact(model, i):
     bfrom_i = tp[find(fr[tp] == i)]  # branches from bus i with transformer
     bto_i = tp[find(to[tp] == i)]  # branches to bus i with transformer
     allbut_i = find(bus[:, BUS_I] != i)  # Set of other buses
     if i in gb:
         return model.Pg[i]-Pd[i] == sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                                         cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * cos(model.va[i] -
                    model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * cos(model.va[i] -
                    model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j]**2 - 1) *
                                        np.cos(- ang(yk[j])) for j in bfrom_i) + real(y[i, i]))
     else:
         return sum(model.vm[i] * model.vm[j] * abs(y[i, j]) *
                    cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in allbut_i) - \
                sum(model.vm[i] * model.vm[to[j]] * abs(yk[j]) * cos(model.va[i] -
                    model.va[to[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bfrom_i) - \
                sum(model.vm[i] * model.vm[fr[j]] * abs(yk[j]) * cos(model.va[i] -
                    model.va[fr[j]] - ang(yk[j])) * (1 / model.tr[j] - 1) for j in bto_i) + \
                model.vm[i] ** 2 * (sum(abs(yk[j]) * (1 / model.tr[j]**2 - 1) *
                                        np.cos(- ang(yk[j])) for j in bfrom_i) + real(y[i, i])) == -Pd[i]
예제 #10
0
def solveropfnlp_2(ppc, solver="ipopt"):
    if solver == "ipopt":
        opt = SolverFactory("ipopt", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/ipopt-linux64/ipopt")
    if solver == "bonmin":
        opt = SolverFactory("bonmin", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/bonmin-linux64/bonmin")
    if solver == "knitro":
        opt = SolverFactory("knitro", executable="D:/ICT/Artelys/Knitro 10.2.1/knitroampl/knitroampl")

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

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

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

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

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

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

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

    start_time = time.clock()

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

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

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

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

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

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

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

    # create a new optimization model
    model = ConcreteModel()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # ppc solved case is returned
    return ppc
예제 #11
0
 def qto(model, i):
     return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \
                           model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \
                           sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
예제 #12
0
 def pto(model, i):
     return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \
                           model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \
                           cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i]))
예제 #13
0
 def qfrom(model, i):
     return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.sin(-ang(yft[i])) - \
                           model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \
                           sin(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))
예제 #14
0
 def pfrom(model, i):
     return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.cos(-ang(yft[i])) - \
                           model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \
                           cos(model.va[fr[i]] - model.va[to[i]] - ang(yk[i]))
예제 #15
0
def solveropfnlp_4(ppc, solver="ipopt"):
    if solver == "ipopt":
        opt = SolverFactory(
            "ipopt",
            executable=
            "/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/ipopt-linux64/ipopt"
        )
    if solver == "bonmin":
        opt = SolverFactory(
            "bonmin",
            executable=
            "/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/bonmin-linux64/bonmin"
        )
    if solver == "knitro":
        opt = SolverFactory(
            "knitro",
            executable="D:/ICT/Artelys/Knitro 10.2.1/knitroampl/knitroampl")

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

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

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

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

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

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

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

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

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

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

    start_time = time.clock()

    # Admittance matrix computation
    # =============================================================
    # Set tap ratios and shunt elements to neutral position
    branch[:, TAP] = 1
    bus[:, BS] = 0

    y = makeYbus(baseMVA, bus, branch)[0]  # admittance matrix
    yk = 1. / (r + x * 1j)  # branch admittance
    yft = yk + 0.5j * b  # branch admittance + susceptance
    gk = yk.real  # branch resistance

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

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

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

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

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

    # create a new optimization model
    model = ConcreteModel()

    # Define sets
    # ------------
    model.bus = Set(ordered=True, initialize=range(nb))  # Set of all buses
    model.gen = Set(ordered=True,
                    initialize=gb)  # Set of buses with generation
    model.line = Set(ordered=True, initialize=range(nl))  # Set of all lines
    model.taps = Set(ordered=True,
                     initialize=tp)  # Set of all lines with tap changers
    model.shunt = Set(ordered=True,
                      initialize=sd)  # Set of buses with shunt elements

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # Update the case info with the optimized variables and approximate the continuous variables to discrete values
    # ==============================================================================================================
    for i in range(nb):
        if i in sd:
            bus[i, BS] = round(model.s[i].value) * Bs0[i] * baseMVA
        bus[i, VM] = model.vm[i].value  # Bus voltage magnitudes
        bus[i, VA] = model.va[i].value * 180 / pi  # Bus voltage angles
    # Update transformation ratios
    for i in range(nl):
        if i in tp:
            branch[i, TAP] = 1 + dudtap * round(model.tap[i].value)
    # Update gen matrix variables
    for i in range(ng):
        gen[i, PG] = model.Pg[gb[i]].value * baseMVA
        gen[i, QG] = model.Qg[gb[i]].value * baseMVA
        gen[i, VG] = bus[gb[i], VM]
    # Convert to external (original) numbering and save case results
    ppc = int2ext(ppc)
    ppc['bus'][:, 1:] = bus[:, 1:]
    branch[:, 0:2] = ppc['branch'][:, 0:2]
    ppc['branch'] = branch
    ppc['gen'][:, 1:] = gen[:, 1:]

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

    # ppc solved case is returned
    return sol