def t_makeLODF(quiet=False): """Tests for C{makeLODF}. @author: Ray Zimmerman (PSERC Cornell) @author: Richard Lincoln """ ntests = 31 t_begin(ntests, quiet) tdir = dirname(__file__) casefile = join(tdir, 't_auction_case') verbose = 0 #not quiet ## load case ppc = loadcase(casefile) ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0) r = rundcopf(ppc, ppopt) baseMVA, bus, gen, branch = r['baseMVA'], r['bus'], r['gen'], r['branch'] _, bus, gen, branch = ext2int1(bus, gen, branch) ## compute injections and flows F0 = branch[:, PF] ## create some PTDF matrices H = makePTDF(baseMVA, bus, branch, 0) ## create some PTDF matrices try: LODF = makeLODF(branch, H) except ZeroDivisionError: pass ## take out non-essential lines one-by-one and see what happens ppc['bus'] = bus ppc['gen'] = gen branch0 = branch outages = r_[arange(12), arange(13, 15), arange(16, 18), [19], arange(26, 33), arange(34, 41)] for k in outages: ppc['branch'] = branch0.copy() ppc['branch'][k, BR_STATUS] = 0 r, _ = rundcpf(ppc, ppopt) baseMVA, bus, gen, branch = \ r['baseMVA'], r['bus'], r['gen'], r['branch'] F = branch[:, PF] t_is(LODF[:, k], (F - F0) / F0[k], 6, 'LODF[:, %d]' % k) t_end()
def t_makeLODF(quiet=False): """Tests for C{makeLODF}. @author: Ray Zimmerman (PSERC Cornell) @author: Richard Lincoln """ ntests = 31 t_begin(ntests, quiet) tdir = dirname(__file__) casefile = join(tdir, 't_auction_case') verbose = 0#not quiet ## load case ppc = loadcase(casefile) ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0) r = rundcopf(ppc, ppopt) baseMVA, bus, gen, branch = r['baseMVA'], r['bus'], r['gen'], r['branch'] _, bus, gen, branch = ext2int1(bus, gen, branch) ## compute injections and flows F0 = branch[:, PF] ## create some PTDF matrices H = makePTDF(baseMVA, bus, branch, 0) ## create some PTDF matrices try: LODF = makeLODF(branch, H) except ZeroDivisionError: pass ## take out non-essential lines one-by-one and see what happens ppc['bus'] = bus ppc['gen'] = gen branch0 = branch outages = r_[arange(12), arange(13, 15), arange(16, 18), [19], arange(26, 33), arange(34, 41)] for k in outages: ppc['branch'] = branch0.copy() ppc['branch'][k, BR_STATUS] = 0 r, _ = rundcpf(ppc, ppopt) baseMVA, bus, gen, branch = \ r['baseMVA'], r['bus'], r['gen'], r['branch'] F = branch[:, PF] t_is(LODF[:, k], (F - F0) / F0[k], 6, 'LODF[:, %d]' % k) t_end()
def t_hessian(quiet=False): """Numerical tests of 2nd derivative code. @author: Ray Zimmerman (PSERC Cornell) """ t_begin(44, quiet) ## run powerflow to get solved case ppopt = ppoption(VERBOSE=0, OUT_ALL=0) results, _ = runpf(case30(), ppopt) baseMVA, bus, gen, branch = \ results['baseMVA'], results['bus'], results['gen'], results['branch'] ## switch to internal bus numbering and build admittance matrices _, bus, gen, branch = ext2int1(bus, gen, branch) Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch) Vm = bus[:, VM] Va = bus[:, VA] * (pi / 180) V = Vm * exp(1j * Va) f = branch[:, F_BUS] ## list of "from" buses t = branch[:, T_BUS] ## list of "to" buses nl = len(f) nb = len(V) Cf = sparse((ones(nl), (range(nl), f)), (nl, nb)) ## connection matrix for line & from buses Ct = sparse((ones(nl), (range(nl), t)), (nl, nb)) ## connection matrix for line & to buses pert = 1e-8 ##----- check d2Sbus_dV2 code ----- t = ' - d2Sbus_dV2 (complex power injections)' lam = 10 * random.rand(nb) num_Haa = zeros((nb, nb), complex) num_Hav = zeros((nb, nb), complex) num_Hva = zeros((nb, nb), complex) num_Hvv = zeros((nb, nb), complex) dSbus_dVm, dSbus_dVa = dSbus_dV(Ybus, V) Haa, Hav, Hva, Hvv = d2Sbus_dV2(Ybus, V, lam) for i in range(nb): Vap = V.copy() Vap[i] = Vm[i] * exp(1j * (Va[i] + pert)) dSbus_dVm_ap, dSbus_dVa_ap = dSbus_dV(Ybus, Vap) num_Haa[:, i] = (dSbus_dVa_ap - dSbus_dVa).T * lam / pert num_Hva[:, i] = (dSbus_dVm_ap - dSbus_dVm).T * lam / pert Vmp = V.copy() Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i]) dSbus_dVm_mp, dSbus_dVa_mp = dSbus_dV(Ybus, Vmp) num_Hav[:, i] = (dSbus_dVa_mp - dSbus_dVa).T * lam / pert num_Hvv[:, i] = (dSbus_dVm_mp - dSbus_dVm).T * lam / pert t_is(Haa.todense(), num_Haa, 4, ['Haa', t]) t_is(Hav.todense(), num_Hav, 4, ['Hav', t]) t_is(Hva.todense(), num_Hva, 4, ['Hva', t]) t_is(Hvv.todense(), num_Hvv, 4, ['Hvv', t]) ##----- check d2Sbr_dV2 code ----- t = ' - d2Sbr_dV2 (complex power flows)' lam = 10 * random.rand(nl) # lam = [1 zeros(nl-1, 1)] num_Gfaa = zeros((nb, nb), complex) num_Gfav = zeros((nb, nb), complex) num_Gfva = zeros((nb, nb), complex) num_Gfvv = zeros((nb, nb), complex) num_Gtaa = zeros((nb, nb), complex) num_Gtav = zeros((nb, nb), complex) num_Gtva = zeros((nb, nb), complex) num_Gtvv = zeros((nb, nb), complex) dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, _, _ = dSbr_dV(branch, Yf, Yt, V) Gfaa, Gfav, Gfva, Gfvv = d2Sbr_dV2(Cf, Yf, V, lam) Gtaa, Gtav, Gtva, Gtvv = d2Sbr_dV2(Ct, Yt, V, lam) for i in range(nb): Vap = V.copy() Vap[i] = Vm[i] * exp(1j * (Va[i] + pert)) dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap = \ dSbr_dV(branch, Yf, Yt, Vap) num_Gfaa[:, i] = (dSf_dVa_ap - dSf_dVa).T * lam / pert num_Gfva[:, i] = (dSf_dVm_ap - dSf_dVm).T * lam / pert num_Gtaa[:, i] = (dSt_dVa_ap - dSt_dVa).T * lam / pert num_Gtva[:, i] = (dSt_dVm_ap - dSt_dVm).T * lam / pert Vmp = V.copy() Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i]) dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp = \ dSbr_dV(branch, Yf, Yt, Vmp) num_Gfav[:, i] = (dSf_dVa_mp - dSf_dVa).T * lam / pert num_Gfvv[:, i] = (dSf_dVm_mp - dSf_dVm).T * lam / pert num_Gtav[:, i] = (dSt_dVa_mp - dSt_dVa).T * lam / pert num_Gtvv[:, i] = (dSt_dVm_mp - dSt_dVm).T * lam / pert t_is(Gfaa.todense(), num_Gfaa, 4, ['Gfaa', t]) t_is(Gfav.todense(), num_Gfav, 4, ['Gfav', t]) t_is(Gfva.todense(), num_Gfva, 4, ['Gfva', t]) t_is(Gfvv.todense(), num_Gfvv, 4, ['Gfvv', t]) t_is(Gtaa.todense(), num_Gtaa, 4, ['Gtaa', t]) t_is(Gtav.todense(), num_Gtav, 4, ['Gtav', t]) t_is(Gtva.todense(), num_Gtva, 4, ['Gtva', t]) t_is(Gtvv.todense(), num_Gtvv, 4, ['Gtvv', t]) ##----- check d2Ibr_dV2 code ----- t = ' - d2Ibr_dV2 (complex currents)' lam = 10 * random.rand(nl) # lam = [1, zeros(nl-1)] num_Gfaa = zeros((nb, nb), complex) num_Gfav = zeros((nb, nb), complex) num_Gfva = zeros((nb, nb), complex) num_Gfvv = zeros((nb, nb), complex) num_Gtaa = zeros((nb, nb), complex) num_Gtav = zeros((nb, nb), complex) num_Gtva = zeros((nb, nb), complex) num_Gtvv = zeros((nb, nb), complex) dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, _, _ = dIbr_dV(branch, Yf, Yt, V) Gfaa, Gfav, Gfva, Gfvv = d2Ibr_dV2(Yf, V, lam) Gtaa, Gtav, Gtva, Gtvv = d2Ibr_dV2(Yt, V, lam) for i in range(nb): Vap = V.copy() Vap[i] = Vm[i] * exp(1j * (Va[i] + pert)) dIf_dVa_ap, dIf_dVm_ap, dIt_dVa_ap, dIt_dVm_ap, If_ap, It_ap = \ dIbr_dV(branch, Yf, Yt, Vap) num_Gfaa[:, i] = (dIf_dVa_ap - dIf_dVa).T * lam / pert num_Gfva[:, i] = (dIf_dVm_ap - dIf_dVm).T * lam / pert num_Gtaa[:, i] = (dIt_dVa_ap - dIt_dVa).T * lam / pert num_Gtva[:, i] = (dIt_dVm_ap - dIt_dVm).T * lam / pert Vmp = V.copy() Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i]) dIf_dVa_mp, dIf_dVm_mp, dIt_dVa_mp, dIt_dVm_mp, If_mp, It_mp = \ dIbr_dV(branch, Yf, Yt, Vmp) num_Gfav[:, i] = (dIf_dVa_mp - dIf_dVa).T * lam / pert num_Gfvv[:, i] = (dIf_dVm_mp - dIf_dVm).T * lam / pert num_Gtav[:, i] = (dIt_dVa_mp - dIt_dVa).T * lam / pert num_Gtvv[:, i] = (dIt_dVm_mp - dIt_dVm).T * lam / pert t_is(Gfaa.todense(), num_Gfaa, 4, ['Gfaa', t]) t_is(Gfav.todense(), num_Gfav, 4, ['Gfav', t]) t_is(Gfva.todense(), num_Gfva, 4, ['Gfva', t]) t_is(Gfvv.todense(), num_Gfvv, 4, ['Gfvv', t]) t_is(Gtaa.todense(), num_Gtaa, 4, ['Gtaa', t]) t_is(Gtav.todense(), num_Gtav, 4, ['Gtav', t]) t_is(Gtva.todense(), num_Gtva, 4, ['Gtva', t]) t_is(Gtvv.todense(), num_Gtvv, 4, ['Gtvv', t]) ##----- check d2ASbr_dV2 code ----- t = ' - d2ASbr_dV2 (squared apparent power flows)' lam = 10 * random.rand(nl) # lam = [1 zeros(nl-1, 1)] num_Gfaa = zeros((nb, nb), complex) num_Gfav = zeros((nb, nb), complex) num_Gfva = zeros((nb, nb), complex) num_Gfvv = zeros((nb, nb), complex) num_Gtaa = zeros((nb, nb), complex) num_Gtav = zeros((nb, nb), complex) num_Gtva = zeros((nb, nb), complex) num_Gtvv = zeros((nb, nb), complex) dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St = dSbr_dV(branch, Yf, Yt, V) dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm = \ dAbr_dV(dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St) Gfaa, Gfav, Gfva, Gfvv = d2ASbr_dV2(dSf_dVa, dSf_dVm, Sf, Cf, Yf, V, lam) Gtaa, Gtav, Gtva, Gtvv = d2ASbr_dV2(dSt_dVa, dSt_dVm, St, Ct, Yt, V, lam) for i in range(nb): Vap = V.copy() Vap[i] = Vm[i] * exp(1j * (Va[i] + pert)) dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap = \ dSbr_dV(branch, Yf, Yt, Vap) dAf_dVa_ap, dAf_dVm_ap, dAt_dVa_ap, dAt_dVm_ap = \ dAbr_dV(dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap) num_Gfaa[:, i] = (dAf_dVa_ap - dAf_dVa).T * lam / pert num_Gfva[:, i] = (dAf_dVm_ap - dAf_dVm).T * lam / pert num_Gtaa[:, i] = (dAt_dVa_ap - dAt_dVa).T * lam / pert num_Gtva[:, i] = (dAt_dVm_ap - dAt_dVm).T * lam / pert Vmp = V.copy() Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i]) dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp = \ dSbr_dV(branch, Yf, Yt, Vmp) dAf_dVa_mp, dAf_dVm_mp, dAt_dVa_mp, dAt_dVm_mp = \ dAbr_dV(dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp) num_Gfav[:, i] = (dAf_dVa_mp - dAf_dVa).T * lam / pert num_Gfvv[:, i] = (dAf_dVm_mp - dAf_dVm).T * lam / pert num_Gtav[:, i] = (dAt_dVa_mp - dAt_dVa).T * lam / pert num_Gtvv[:, i] = (dAt_dVm_mp - dAt_dVm).T * lam / pert t_is(Gfaa.todense(), num_Gfaa, 2, ['Gfaa', t]) t_is(Gfav.todense(), num_Gfav, 2, ['Gfav', t]) t_is(Gfva.todense(), num_Gfva, 2, ['Gfva', t]) t_is(Gfvv.todense(), num_Gfvv, 2, ['Gfvv', t]) t_is(Gtaa.todense(), num_Gtaa, 2, ['Gtaa', t]) t_is(Gtav.todense(), num_Gtav, 2, ['Gtav', t]) t_is(Gtva.todense(), num_Gtva, 2, ['Gtva', t]) t_is(Gtvv.todense(), num_Gtvv, 2, ['Gtvv', t]) ##----- check d2ASbr_dV2 code ----- t = ' - d2ASbr_dV2 (squared real power flows)' lam = 10 * random.rand(nl) # lam = [1 zeros(nl-1, 1)] num_Gfaa = zeros((nb, nb), complex) num_Gfav = zeros((nb, nb), complex) num_Gfva = zeros((nb, nb), complex) num_Gfvv = zeros((nb, nb), complex) num_Gtaa = zeros((nb, nb), complex) num_Gtav = zeros((nb, nb), complex) num_Gtva = zeros((nb, nb), complex) num_Gtvv = zeros((nb, nb), complex) dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St = dSbr_dV(branch, Yf, Yt, V) dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm = \ dAbr_dV(dSf_dVa.real, dSf_dVm.real, dSt_dVa.real, dSt_dVm.real, Sf.real, St.real) Gfaa, Gfav, Gfva, Gfvv = d2ASbr_dV2(dSf_dVa.real, dSf_dVm.real, Sf.real, Cf, Yf, V, lam) Gtaa, Gtav, Gtva, Gtvv = d2ASbr_dV2(dSt_dVa.real, dSt_dVm.real, St.real, Ct, Yt, V, lam) for i in range(nb): Vap = V.copy() Vap[i] = Vm[i] * exp(1j * (Va[i] + pert)) dSf_dVa_ap, dSf_dVm_ap, dSt_dVa_ap, dSt_dVm_ap, Sf_ap, St_ap = \ dSbr_dV(branch, Yf, Yt, Vap) dAf_dVa_ap, dAf_dVm_ap, dAt_dVa_ap, dAt_dVm_ap = \ dAbr_dV(dSf_dVa_ap.real, dSf_dVm_ap.real, dSt_dVa_ap.real, dSt_dVm_ap.real, Sf_ap.real, St_ap.real) num_Gfaa[:, i] = (dAf_dVa_ap - dAf_dVa).T * lam / pert num_Gfva[:, i] = (dAf_dVm_ap - dAf_dVm).T * lam / pert num_Gtaa[:, i] = (dAt_dVa_ap - dAt_dVa).T * lam / pert num_Gtva[:, i] = (dAt_dVm_ap - dAt_dVm).T * lam / pert Vmp = V.copy() Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i]) dSf_dVa_mp, dSf_dVm_mp, dSt_dVa_mp, dSt_dVm_mp, Sf_mp, St_mp = \ dSbr_dV(branch, Yf, Yt, Vmp) dAf_dVa_mp, dAf_dVm_mp, dAt_dVa_mp, dAt_dVm_mp = \ dAbr_dV(dSf_dVa_mp.real, dSf_dVm_mp.real, dSt_dVa_mp.real, dSt_dVm_mp.real, Sf_mp.real, St_mp.real) num_Gfav[:, i] = (dAf_dVa_mp - dAf_dVa).T * lam / pert num_Gfvv[:, i] = (dAf_dVm_mp - dAf_dVm).T * lam / pert num_Gtav[:, i] = (dAt_dVa_mp - dAt_dVa).T * lam / pert num_Gtvv[:, i] = (dAt_dVm_mp - dAt_dVm).T * lam / pert t_is(Gfaa.todense(), num_Gfaa, 2, ['Gfaa', t]) t_is(Gfav.todense(), num_Gfav, 2, ['Gfav', t]) t_is(Gfva.todense(), num_Gfva, 2, ['Gfva', t]) t_is(Gfvv.todense(), num_Gfvv, 2, ['Gfvv', t]) t_is(Gtaa.todense(), num_Gtaa, 2, ['Gtaa', t]) t_is(Gtav.todense(), num_Gtav, 2, ['Gtav', t]) t_is(Gtva.todense(), num_Gtva, 2, ['Gtva', t]) t_is(Gtvv.todense(), num_Gtvv, 2, ['Gtvv', t]) ##----- check d2AIbr_dV2 code ----- t = ' - d2AIbr_dV2 (squared current magnitudes)' lam = 10 * random.rand(nl) # lam = [1 zeros(nl-1, 1)] num_Gfaa = zeros((nb, nb), complex) num_Gfav = zeros((nb, nb), complex) num_Gfva = zeros((nb, nb), complex) num_Gfvv = zeros((nb, nb), complex) num_Gtaa = zeros((nb, nb), complex) num_Gtav = zeros((nb, nb), complex) num_Gtva = zeros((nb, nb), complex) num_Gtvv = zeros((nb, nb), complex) dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It = dIbr_dV(branch, Yf, Yt, V) dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm = \ dAbr_dV(dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It) Gfaa, Gfav, Gfva, Gfvv = d2AIbr_dV2(dIf_dVa, dIf_dVm, If, Yf, V, lam) Gtaa, Gtav, Gtva, Gtvv = d2AIbr_dV2(dIt_dVa, dIt_dVm, It, Yt, V, lam) for i in range(nb): Vap = V.copy() Vap[i] = Vm[i] * exp(1j * (Va[i] + pert)) dIf_dVa_ap, dIf_dVm_ap, dIt_dVa_ap, dIt_dVm_ap, If_ap, It_ap = \ dIbr_dV(branch, Yf, Yt, Vap) dAf_dVa_ap, dAf_dVm_ap, dAt_dVa_ap, dAt_dVm_ap = \ dAbr_dV(dIf_dVa_ap, dIf_dVm_ap, dIt_dVa_ap, dIt_dVm_ap, If_ap, It_ap) num_Gfaa[:, i] = (dAf_dVa_ap - dAf_dVa).T * lam / pert num_Gfva[:, i] = (dAf_dVm_ap - dAf_dVm).T * lam / pert num_Gtaa[:, i] = (dAt_dVa_ap - dAt_dVa).T * lam / pert num_Gtva[:, i] = (dAt_dVm_ap - dAt_dVm).T * lam / pert Vmp = V.copy() Vmp[i] = (Vm[i] + pert) * exp(1j * Va[i]) dIf_dVa_mp, dIf_dVm_mp, dIt_dVa_mp, dIt_dVm_mp, If_mp, It_mp = \ dIbr_dV(branch, Yf, Yt, Vmp) dAf_dVa_mp, dAf_dVm_mp, dAt_dVa_mp, dAt_dVm_mp = \ dAbr_dV(dIf_dVa_mp, dIf_dVm_mp, dIt_dVa_mp, dIt_dVm_mp, If_mp, It_mp) num_Gfav[:, i] = (dAf_dVa_mp - dAf_dVa).T * lam / pert num_Gfvv[:, i] = (dAf_dVm_mp - dAf_dVm).T * lam / pert num_Gtav[:, i] = (dAt_dVa_mp - dAt_dVa).T * lam / pert num_Gtvv[:, i] = (dAt_dVm_mp - dAt_dVm).T * lam / pert t_is(Gfaa.todense(), num_Gfaa, 3, ['Gfaa', t]) t_is(Gfav.todense(), num_Gfav, 3, ['Gfav', t]) t_is(Gfva.todense(), num_Gfva, 3, ['Gfva', t]) t_is(Gfvv.todense(), num_Gfvv, 2, ['Gfvv', t]) t_is(Gtaa.todense(), num_Gtaa, 3, ['Gtaa', t]) t_is(Gtav.todense(), num_Gtav, 3, ['Gtav', t]) t_is(Gtva.todense(), num_Gtva, 3, ['Gtva', t]) t_is(Gtvv.todense(), num_Gtvv, 2, ['Gtvv', t]) t_end()
def t_makePTDF(quiet=False): """Tests for C{makePTDF}. @author: Ray Zimmerman (PSERC Cornell) @author: Richard Lincoln """ ntests = 24 t_begin(ntests, quiet) tdir = dirname(__file__) casefile = join(tdir, 't_case9_opf') verbose = 0 #not quiet ## load case ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0) r = rundcopf(casefile, ppopt) baseMVA, bus, gen, branch = r['baseMVA'], r['bus'], r['gen'], r['branch'] _, bus, gen, branch = ext2int1(bus, gen, branch) nb = bus.shape[0] nbr = branch.shape[0] ng = gen.shape[0] ## compute injections and flows Cg = sparse((ones(ng), (gen[:, GEN_BUS], arange(ng))), (nb, ng)) Pg = Cg * gen[:, PG] Pd = bus[:, PD] P = Pg - Pd ig = find(P > 0) il = find(P <= 0) F = branch[:, PF] ## create corresponding slack distribution matrices e1 = zeros((nb, 1)) e1[0] = 1 e4 = zeros((nb, 1)) e4[3] = 1 D1 = eye(nb, nb) - dot(e1, ones((1, nb))) D4 = eye(nb, nb) - dot(e4, ones((1, nb))) Deq = eye(nb, nb) - ones((nb, 1)) / nb * ones((1, nb)) Dg = eye(nb) - matrix(Pd / sum(Pd)).T * ones(nb) Dd = eye(nb) - matrix(Pg / sum(Pg)).T * ones(nb) ## create some PTDF matrices H1 = makePTDF(baseMVA, bus, branch, 0) H4 = makePTDF(baseMVA, bus, branch, 3) Heq = makePTDF(baseMVA, bus, branch, ones(nb)) Hg = makePTDF(baseMVA, bus, branch, Pd) Hd = makePTDF(baseMVA, bus, branch, Pg) ## matrices get properly transformed by slack dist matrices t_is(H1, dot(H1, D1), 8, 'H1 == H1 * D1') t_is(H4, dot(H1, D4), 8, 'H4 == H1 * D4') t_is(Heq, dot(H1, Deq), 8, 'Heq == H1 * Deq') t_is(Hg, dot(H1, Dg), 8, 'Hg == H1 * Dg') t_is(Hd, dot(H1, Dd), 8, 'Hd == H1 * Dd') t_is(H1, dot(Heq, D1), 8, 'H1 == Heq * D1') t_is(H4, dot(Heq, D4), 8, 'H4 == Heq * D4') t_is(Heq, dot(Heq, Deq), 8, 'Heq == Heq * Deq') t_is(Hg, dot(Heq, Dg), 8, 'Hg == Heq * Dg') t_is(Hd, dot(Heq, Dd), 8, 'Hd == Heq * Dd') t_is(H1, dot(Hg, D1), 8, 'H1 == Hg * D1') t_is(H4, dot(Hg, D4), 8, 'H4 == Hg * D4') t_is(Heq, dot(Hg, Deq), 8, 'Heq == Hg * Deq') t_is(Hg, dot(Hg, Dg), 8, 'Hg == Hg * Dg') t_is(Hd, dot(Hg, Dd), 8, 'Hd == Hg * Dd') ## PTDFs can reconstruct flows t_is(F, dot(H1, P), 3, 'Flow == H1 * P') t_is(F, dot(H4, P), 3, 'Flow == H4 * P') t_is(F, dot(Heq, P), 3, 'Flow == Heq * P') t_is(F, dot(Hg, P), 3, 'Flow == Hg * P') t_is(F, dot(Hd, P), 3, 'Flow == Hd * P') ## other t_is(F, dot(Hg, Pg), 3, 'Flow == Hg * Pg') t_is(F, dot(Hd, (-Pd)), 3, 'Flow == Hd * (-Pd)') t_is(zeros(nbr), dot(Hg, (-Pd)), 3, 'zeros == Hg * (-Pd)') t_is(zeros(nbr), dot(Hd, Pg), 3, 'zeros == Hd * Pg') t_end()
def t_makePTDF(quiet=False): """Tests for C{makePTDF}. @author: Ray Zimmerman (PSERC Cornell) """ ntests = 24 t_begin(ntests, quiet) tdir = dirname(__file__) casefile = join(tdir, 't_case9_opf') verbose = 0#not quiet ## load case ppopt = ppoption(VERBOSE=verbose, OUT_ALL=0) r = rundcopf(casefile, ppopt) baseMVA, bus, gen, branch = r['baseMVA'], r['bus'], r['gen'], r['branch'] _, bus, gen, branch = ext2int1(bus, gen, branch) nb = bus.shape[0] nbr = branch.shape[0] ng = gen.shape[0] ## compute injections and flows Cg = sparse((ones(ng), (gen[:, GEN_BUS], arange(ng))), (nb, ng)) Pg = Cg * gen[:, PG] Pd = bus[:, PD] P = Pg - Pd ig = find(P > 0) il = find(P <= 0) F = branch[:, PF] ## create corresponding slack distribution matrices e1 = zeros((nb, 1)); e1[0] = 1 e4 = zeros((nb, 1)); e4[3] = 1 D1 = eye(nb, nb) - dot(e1, ones((1, nb))) D4 = eye(nb, nb) - dot(e4, ones((1, nb))) Deq = eye(nb, nb) - ones((nb, 1)) / nb * ones((1, nb)) Dg = eye(nb) - matrix( Pd / sum(Pd) ).T * ones(nb) Dd = eye(nb) - matrix( Pg / sum(Pg) ).T * ones(nb) ## create some PTDF matrices H1 = makePTDF(baseMVA, bus, branch, 0) H4 = makePTDF(baseMVA, bus, branch, 3) Heq = makePTDF(baseMVA, bus, branch, ones(nb)) Hg = makePTDF(baseMVA, bus, branch, Pd) Hd = makePTDF(baseMVA, bus, branch, Pg) ## matrices get properly transformed by slack dist matrices t_is(H1, dot(H1, D1), 8, 'H1 == H1 * D1') t_is(H4, dot(H1, D4), 8, 'H4 == H1 * D4') t_is(Heq, dot(H1, Deq), 8, 'Heq == H1 * Deq') t_is(Hg, dot(H1, Dg), 8, 'Hg == H1 * Dg') t_is(Hd, dot(H1, Dd), 8, 'Hd == H1 * Dd') t_is(H1, dot(Heq, D1), 8, 'H1 == Heq * D1') t_is(H4, dot(Heq, D4), 8, 'H4 == Heq * D4') t_is(Heq, dot(Heq, Deq), 8, 'Heq == Heq * Deq') t_is(Hg, dot(Heq, Dg), 8, 'Hg == Heq * Dg') t_is(Hd, dot(Heq, Dd), 8, 'Hd == Heq * Dd') t_is(H1, dot(Hg, D1), 8, 'H1 == Hg * D1') t_is(H4, dot(Hg, D4), 8, 'H4 == Hg * D4') t_is(Heq, dot(Hg, Deq), 8, 'Heq == Hg * Deq') t_is(Hg, dot(Hg, Dg), 8, 'Hg == Hg * Dg') t_is(Hd, dot(Hg, Dd), 8, 'Hd == Hg * Dd') ## PTDFs can reconstruct flows t_is(F, dot(H1, P), 3, 'Flow == H1 * P') t_is(F, dot(H4, P), 3, 'Flow == H4 * P') t_is(F, dot(Heq, P), 3, 'Flow == Heq * P') t_is(F, dot(Hg, P), 3, 'Flow == Hg * P') t_is(F, dot(Hd, P), 3, 'Flow == Hd * P') ## other t_is(F, dot(Hg, Pg), 3, 'Flow == Hg * Pg') t_is(F, dot(Hd, (-Pd)), 3, 'Flow == Hd * (-Pd)') t_is(zeros(nbr), dot(Hg, (-Pd)), 3, 'zeros == Hg * (-Pd)') t_is(zeros(nbr), dot(Hd, Pg), 3, 'zeros == Hd * Pg') t_end()
def t_jacobian(quiet=False): """Numerical tests of partial derivative code. @author: Ray Zimmerman (PSERC Cornell) """ t_begin(28, quiet) ## run powerflow to get solved case ppopt = ppoption(VERBOSE=0, OUT_ALL=0) ppc = loadcase(case30()) results, _ = runpf(ppc, ppopt) baseMVA, bus, gen, branch = \ results['baseMVA'], results['bus'], results['gen'], results['branch'] ## switch to internal bus numbering and build admittance matrices _, bus, gen, branch = ext2int1(bus, gen, branch) Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch) Ybus_full = Ybus.todense() Yf_full = Yf.todense() Yt_full = Yt.todense() Vm = bus[:, VM] Va = bus[:, VA] * (pi / 180) V = Vm * exp(1j * Va) f = branch[:, F_BUS].astype(int) ## list of "from" buses t = branch[:, T_BUS].astype(int) ## list of "to" buses #nl = len(f) nb = len(V) pert = 1e-8 Vm = array([Vm]).T # column array Va = array([Va]).T # column array Vc = array([V]).T # column array ##----- check dSbus_dV code ----- ## full matrices dSbus_dVm_full, dSbus_dVa_full = dSbus_dV(Ybus_full, V) ## sparse matrices dSbus_dVm, dSbus_dVa = dSbus_dV(Ybus, V) dSbus_dVm_sp = dSbus_dVm.todense() dSbus_dVa_sp = dSbus_dVa.todense() ## compute numerically to compare Vmp = (Vm * ones((1, nb)) + pert*eye(nb)) * (exp(1j * Va) * ones((1, nb))) Vap = (Vm * ones((1, nb))) * (exp(1j * (Va*ones((1, nb)) + pert*eye(nb)))) num_dSbus_dVm = (Vmp * conj(Ybus * Vmp) - Vc * ones((1, nb)) * conj(Ybus * Vc * ones((1, nb)))) / pert num_dSbus_dVa = (Vap * conj(Ybus * Vap) - Vc * ones((1, nb)) * conj(Ybus * Vc * ones((1, nb)))) / pert t_is(dSbus_dVm_sp, num_dSbus_dVm, 5, 'dSbus_dVm (sparse)') t_is(dSbus_dVa_sp, num_dSbus_dVa, 5, 'dSbus_dVa (sparse)') t_is(dSbus_dVm_full, num_dSbus_dVm, 5, 'dSbus_dVm (full)') t_is(dSbus_dVa_full, num_dSbus_dVa, 5, 'dSbus_dVa (full)') ##----- check dSbr_dV code ----- ## full matrices dSf_dVa_full, dSf_dVm_full, dSt_dVa_full, dSt_dVm_full, _, _ = \ dSbr_dV(branch, Yf_full, Yt_full, V) ## sparse matrices dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St = dSbr_dV(branch, Yf, Yt, V) dSf_dVa_sp = dSf_dVa.todense() dSf_dVm_sp = dSf_dVm.todense() dSt_dVa_sp = dSt_dVa.todense() dSt_dVm_sp = dSt_dVm.todense() ## compute numerically to compare Vmpf = Vmp[f, :] Vapf = Vap[f, :] Vmpt = Vmp[t, :] Vapt = Vap[t, :] Sf2 = (Vc[f] * ones((1, nb))) * conj(Yf * Vc * ones((1, nb))) St2 = (Vc[t] * ones((1, nb))) * conj(Yt * Vc * ones((1, nb))) Smpf = Vmpf * conj(Yf * Vmp) Sapf = Vapf * conj(Yf * Vap) Smpt = Vmpt * conj(Yt * Vmp) Sapt = Vapt * conj(Yt * Vap) num_dSf_dVm = (Smpf - Sf2) / pert num_dSf_dVa = (Sapf - Sf2) / pert num_dSt_dVm = (Smpt - St2) / pert num_dSt_dVa = (Sapt - St2) / pert t_is(dSf_dVm_sp, num_dSf_dVm, 5, 'dSf_dVm (sparse)') t_is(dSf_dVa_sp, num_dSf_dVa, 5, 'dSf_dVa (sparse)') t_is(dSt_dVm_sp, num_dSt_dVm, 5, 'dSt_dVm (sparse)') t_is(dSt_dVa_sp, num_dSt_dVa, 5, 'dSt_dVa (sparse)') t_is(dSf_dVm_full, num_dSf_dVm, 5, 'dSf_dVm (full)') t_is(dSf_dVa_full, num_dSf_dVa, 5, 'dSf_dVa (full)') t_is(dSt_dVm_full, num_dSt_dVm, 5, 'dSt_dVm (full)') t_is(dSt_dVa_full, num_dSt_dVa, 5, 'dSt_dVa (full)') ##----- check dAbr_dV code ----- ## full matrices dAf_dVa_full, dAf_dVm_full, dAt_dVa_full, dAt_dVm_full = \ dAbr_dV(dSf_dVa_full, dSf_dVm_full, dSt_dVa_full, dSt_dVm_full, Sf, St) ## sparse matrices dAf_dVa, dAf_dVm, dAt_dVa, dAt_dVm = \ dAbr_dV(dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St) dAf_dVa_sp = dAf_dVa.todense() dAf_dVm_sp = dAf_dVm.todense() dAt_dVa_sp = dAt_dVa.todense() dAt_dVm_sp = dAt_dVm.todense() ## compute numerically to compare num_dAf_dVm = (abs(Smpf)**2 - abs(Sf2)**2) / pert num_dAf_dVa = (abs(Sapf)**2 - abs(Sf2)**2) / pert num_dAt_dVm = (abs(Smpt)**2 - abs(St2)**2) / pert num_dAt_dVa = (abs(Sapt)**2 - abs(St2)**2) / pert t_is(dAf_dVm_sp, num_dAf_dVm, 4, 'dAf_dVm (sparse)') t_is(dAf_dVa_sp, num_dAf_dVa, 4, 'dAf_dVa (sparse)') t_is(dAt_dVm_sp, num_dAt_dVm, 4, 'dAt_dVm (sparse)') t_is(dAt_dVa_sp, num_dAt_dVa, 4, 'dAt_dVa (sparse)') t_is(dAf_dVm_full, num_dAf_dVm, 4, 'dAf_dVm (full)') t_is(dAf_dVa_full, num_dAf_dVa, 4, 'dAf_dVa (full)') t_is(dAt_dVm_full, num_dAt_dVm, 4, 'dAt_dVm (full)') t_is(dAt_dVa_full, num_dAt_dVa, 4, 'dAt_dVa (full)') ##----- check dIbr_dV code ----- ## full matrices dIf_dVa_full, dIf_dVm_full, dIt_dVa_full, dIt_dVm_full, _, _ = \ dIbr_dV(branch, Yf_full, Yt_full, V) ## sparse matrices dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, _, _ = dIbr_dV(branch, Yf, Yt, V) dIf_dVa_sp = dIf_dVa.todense() dIf_dVm_sp = dIf_dVm.todense() dIt_dVa_sp = dIt_dVa.todense() dIt_dVm_sp = dIt_dVm.todense() ## compute numerically to compare num_dIf_dVm = (Yf * Vmp - Yf * Vc * ones((1, nb))) / pert num_dIf_dVa = (Yf * Vap - Yf * Vc * ones((1, nb))) / pert num_dIt_dVm = (Yt * Vmp - Yt * Vc * ones((1, nb))) / pert num_dIt_dVa = (Yt * Vap - Yt * Vc * ones((1, nb))) / pert t_is(dIf_dVm_sp, num_dIf_dVm, 5, 'dIf_dVm (sparse)') t_is(dIf_dVa_sp, num_dIf_dVa, 5, 'dIf_dVa (sparse)') t_is(dIt_dVm_sp, num_dIt_dVm, 5, 'dIt_dVm (sparse)') t_is(dIt_dVa_sp, num_dIt_dVa, 5, 'dIt_dVa (sparse)') t_is(dIf_dVm_full, num_dIf_dVm, 5, 'dIf_dVm (full)') t_is(dIf_dVa_full, num_dIf_dVa, 5, 'dIf_dVa (full)') t_is(dIt_dVm_full, num_dIt_dVm, 5, 'dIt_dVm (full)') t_is(dIt_dVa_full, num_dIt_dVa, 5, 'dIt_dVa (full)') t_end()