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]
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]
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]))
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]))
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)
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)
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)
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]
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]
def solveropfnlp_2(ppc, solver="ipopt"): if solver == "ipopt": opt = SolverFactory("ipopt", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/ipopt-linux64/ipopt") if solver == "bonmin": opt = SolverFactory("bonmin", executable="/home/iso/PycharmProjects/opfLC_python3/Python3/py_solvers/bonmin-linux64/bonmin") if solver == "knitro": opt = SolverFactory("knitro", executable="D:/ICT/Artelys/Knitro 10.2.1/knitroampl/knitroampl") ppc = ext2int(ppc) # convert to continuous indexing starting from 0 # Gather information about the system # ============================================================= baseMVA, bus, gen, branch = \ ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc["branch"] nb = bus.shape[0] # number of buses ng = gen.shape[0] # number of generators nl = branch.shape[0] # number of lines # generator buses gb = tolist(np.array(gen[:, GEN_BUS]).astype(int)) sb = find((bus[:, BUS_TYPE] == REF)) # slack bus index fr = branch[:, F_BUS].astype(int) # from bus indices to = branch[:, T_BUS].astype(int) # to bus indices tr = branch[:, TAP] # transformation ratios tr[find(tr == 0)] = 1 # set to 1 transformation ratios that are 0 r = branch[:, BR_R] # branch resistances x = branch[:, BR_X] # branch reactances b = branch[:, BR_B] # branch susceptances start_time = time.clock() # Admittance matrix computation # ============================================================= y = makeYbus(baseMVA, bus, branch)[0] # admittance matrix yk = 1./(r+x*1j) # branch admittance yft = yk + 0.5j*b # branch admittance + susceptance gk = yk.real # branch resistance yk = yk/tr # include /tr in yk # Optimization # ============================================================= branch[find(branch[:, RATE_A] == 0), RATE_A] = 9999 # set undefined Sflow limit to 9999 Smax = branch[:, RATE_A] / baseMVA # Max. Sflow # Power demand parameters Pd = bus[:, PD] / baseMVA Qd = bus[:, QD] / baseMVA # Max and min Pg and Qg Pg_max = zeros(nb) Pg_max[gb] = gen[:, PMAX] / baseMVA Pg_min = zeros(nb) Pg_min[gb] = gen[:, PMIN] / baseMVA Qg_max = zeros(nb) Qg_max[gb] = gen[:, QMAX] / baseMVA Qg_min = zeros(nb) Qg_min[gb] = gen[:, QMIN] / baseMVA # Vmax and Vmin vectors Vmax = bus[:, VMAX] Vmin = bus[:, VMIN] vm = bus[:, VM] va = bus[:, VA]*pi/180 # create a new optimization model model = ConcreteModel() # Define sets # ------------ model.bus = Set(ordered=True, initialize=range(nb)) # Set of all buses model.gen = Set(ordered=True, initialize=gb) # Set of buses with generation model.line = Set(ordered=True, initialize=range(nl)) # Set of all lines # Define variables # ----------------- # Voltage magnitudes vector (vm) model.vm = Var(model.bus) # Voltage angles vector (va) model.va = Var(model.bus) # Reactive power generation, synchronous machines(SM) (Qg) model.Qg = Var(model.gen) Qg0 = zeros(nb) Qg0[gb] = gen[:, QG]/baseMVA # Active power generation, synchronous machines(SM) (Pg) model.Pg = Var(model.gen) Pg0 = zeros(nb) Pg0[gb] = gen[:, PG] / baseMVA # Active and reactive power from at all branches model.Pf = Var(model.line) model.Qf = Var(model.line) # Active and reactive power to at all branches model.Pt = Var(model.line) model.Qt = Var(model.line) # Warm start the problem # ------------------------ for i in range(nb): model.vm[i] = vm[i] model.va[i] = va[i] if i in gb: model.Pg[i] = Pg0[i] model.Qg[i] = Qg0[i] for i in range(nl): model.Pf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.cos(-ang(yft[i])) -\ vm[fr[i]] * vm[to[i]] * abs(yk[i]) * np.cos(va[fr[i]] - va[to[i]] - ang(yk[i])) model.Qf[i] = vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.sin(-ang(yft[i])) -\ vm[fr[i]] * vm[to[i]] * abs(yk[i]) * np.sin(va[fr[i]] - va[to[i]] - ang(yk[i])) model.Pt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) -\ vm[to[i]] * vm[fr[i]] * abs(yk[i]) * np.cos(va[to[i]] - va[fr[i]] - ang(yk[i])) model.Qt[i] = vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) -\ vm[to[i]] * vm[fr[i]] * abs(yk[i]) * np.sin(va[to[i]] - va[fr[i]] - ang(yk[i])) # Define constraints # ---------------------------- # Equalities: # ------------ # Active power flow equalities def powerflowact(model, i): if i in gb: return model.Pg[i]-Pd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb)) else: return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * cos(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb)) == -Pd[i] model.const1 = Constraint(model.bus, rule=powerflowact) # Reactive power flow equalities def powerflowreact(model, i): if i in gb: return model.Qg[i]-Qd[i] == sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb)) else: return sum(model.vm[i]*model.vm[j]*abs(y[i, j]) * sin(model.va[i] - model.va[j] - ang(y[i, j])) for j in range(nb)) == -Qd[i] model.const2 = Constraint(model.bus, rule=powerflowreact) # Active power from def pfrom(model, i): return model.Pf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.cos(-ang(yft[i])) - \ model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \ cos(model.va[fr[i]] - model.va[to[i]] - ang(yk[i])) model.const3 = Constraint(model.line, rule=pfrom) # Reactive power from def qfrom(model, i): return model.Qf[i] == model.vm[fr[i]] ** 2 * abs(yft[i]) / (tr[i] ** 2) * np.sin(-ang(yft[i])) - \ model.vm[fr[i]] * model.vm[to[i]] * abs(yk[i]) * \ sin(model.va[fr[i]] - model.va[to[i]] - ang(yk[i])) model.const4 = Constraint(model.line, rule=qfrom) # Active power to def pto(model, i): return model.Pt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.cos(-ang(yft[i])) - \ model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \ cos(model.va[to[i]] - model.va[fr[i]] - ang(yk[i])) model.const5 = Constraint(model.line, rule=pto) # Reactive power to def qto(model, i): return model.Qt[i] == model.vm[to[i]] ** 2 * abs(yft[i]) * np.sin(-ang(yft[i])) - \ model.vm[to[i]] * model.vm[fr[i]] * abs(yk[i]) * \ sin(model.va[to[i]] - model.va[fr[i]] - ang(yk[i])) model.const6 = Constraint(model.line, rule=qto) # Slack bus phase angle model.const7 = Constraint(expr=model.va[sb[0]] == 0) # Inequalities: # ---------------- # Active power generator limits Pg_min <= Pg <= Pg_max def genplimits(model, i): return Pg_min[i] <= model.Pg[i] <= Pg_max[i] model.const8 = Constraint(model.gen, rule=genplimits) # Reactive power generator limits Qg_min <= Qg <= Qg_max def genqlimits(model, i): return Qg_min[i] <= model.Qg[i] <= Qg_max[i] model.const9 = Constraint(model.gen, rule=genqlimits) # Voltage constraints ( Vmin <= V <= Vmax ) def vlimits(model, i): return Vmin[i] <= model.vm[i] <= Vmax[i] model.const10 = Constraint(model.bus, rule=vlimits) # Sfrom line limit def sfrommax(model, i): return model.Pf[i]**2 + model.Qf[i]**2 <= Smax[i]**2 model.const11 = Constraint(model.line, rule=sfrommax) # Sto line limit def stomax(model, i): return model.Pt[i]**2 + model.Qt[i]**2 <= Smax[i]**2 model.const12 = Constraint(model.line, rule=stomax) # Set objective function # ------------------------ def obj_fun(model): return sum(gk[i] * ((model.vm[fr[i]] / tr[i])**2 + model.vm[to[i]]**2 - 2/tr[i] * model.vm[fr[i]] * model.vm[to[i]] * cos(model.va[fr[i]] - model.va[to[i]])) for i in range(nl)) model.obj = Objective(rule=obj_fun, sense=minimize) mt = time.clock() - start_time # Modeling time # Execute solve command with the selected solver # ------------------------------------------------ start_time = time.clock() results = opt.solve(model, tee=True) et = time.clock() - start_time # Elapsed time print(results) # Update the case info with the optimized variables # ================================================== for i in range(nb): bus[i, VM] = model.vm[i].value # Bus voltage magnitudes bus[i, VA] = model.va[i].value*180/pi # Bus voltage angles # Include Pf - Qf - Pt - Qt in the branch matrix branchsol = zeros((nl, 17)) branchsol[:, :-4] = branch for i in range(nl): branchsol[i, PF] = model.Pf[i].value * baseMVA branchsol[i, QF] = model.Qf[i].value * baseMVA branchsol[i, PT] = model.Pt[i].value * baseMVA branchsol[i, QT] = model.Qt[i].value * baseMVA # Update gen matrix variables for i in range(ng): gen[i, PG] = model.Pg[gb[i]].value * baseMVA gen[i, QG] = model.Qg[gb[i]].value * baseMVA gen[i, VG] = bus[gb[i], VM] # Convert to external (original) numbering and save case results ppc = int2ext(ppc) ppc['bus'][:, 1:] = bus[:, 1:] branchsol[:, 0:2] = ppc['branch'][:, 0:2] ppc['branch'] = branchsol ppc['gen'][:, 1:] = gen[:, 1:] ppc['obj'] = value(obj_fun(model)) ppc['ploss'] = value(obj_fun(model)) * baseMVA ppc['et'] = et ppc['mt'] = mt ppc['success'] = 1 # ppc solved case is returned return ppc
def 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]))
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]))
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]))
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]))
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