def t_ext2int2ext(quiet=False): """Tests C{ext2int} and C{int2ext}. @author: Ray Zimmerman (PSERC Cornell) @author: Richard Lincoln """ t_begin(85, quiet) ##----- ppc = e2i_data/i2e_data(ppc) ----- t = 'ppc = e2i_data(ppc) : ' ppce = loadcase(t_case_ext()) ppci = loadcase(t_case_int()) ppc = e2i_data(ppce) t_is(ppc['bus'], ppci['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppci['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppci['gen'], 12, [t, 'gen']) t_is(ppc['gencost'], ppci['gencost'], 12, [t, 'gencost']) t_is(ppc['areas'], ppci['areas'], 12, [t, 'areas']) t_is(ppc['A'], ppci['A'], 12, [t, 'A']) t_is(ppc['N'], ppci['N'], 12, [t, 'N']) t = 'ppc = e2i_data(ppc) - repeat : ' ppc = e2i_data(ppc) t_is(ppc['bus'], ppci['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppci['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppci['gen'], 12, [t, 'gen']) t_is(ppc['gencost'], ppci['gencost'], 12, [t, 'gencost']) t_is(ppc['areas'], ppci['areas'], 12, [t, 'areas']) t_is(ppc['A'], ppci['A'], 12, [t, 'A']) t_is(ppc['N'], ppci['N'], 12, [t, 'N']) t = 'ppc = i2e_data(ppc) : ' ppc = i2e_data(ppc) t_is(ppc['bus'], ppce['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppce['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppce['gen'], 12, [t, 'gen']) t_is(ppc['gencost'], ppce['gencost'], 12, [t, 'gencost']) t_is(ppc['areas'], ppce['areas'], 12, [t, 'areas']) t_is(ppc['A'], ppce['A'], 12, [t, 'A']) t_is(ppc['N'], ppce['N'], 12, [t, 'N']) ##----- val = e2i_data/i2e_data(ppc, val, ...) ----- t = 'val = e2i_data(ppc, val, \'bus\')' ppc = e2i_data(ppce) got = e2i_data(ppc, ppce['xbus'], 'bus') ex = ppce['xbus'] ex = delete(ex, 5, 0) t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, \'bus\')' tmp = ones(ppce['xbus'].shape) tmp[5, :] = ppce['xbus'][5, :] got = i2e_data(ppc, ex, tmp, 'bus') t_is(got, ppce['xbus'], 12, t) t = 'val = e2i_data(ppc, val, \'bus\', 1)' got = e2i_data(ppc, ppce['xbus'], 'bus', 1) ex = ppce['xbus'] ex = delete(ex, 5, 1) t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, \'bus\', 1)' tmp = ones(ppce['xbus'].shape) tmp[:, 5] = ppce['xbus'][:, 5] got = i2e_data(ppc, ex, tmp, 'bus', 1) t_is(got, ppce['xbus'], 12, t) t = 'val = e2i_data(ppc, val, \'gen\')' got = e2i_data(ppc, ppce['xgen'], 'gen') ex = ppce['xgen'][[3, 1, 0], :] t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, \'gen\')' tmp = ones(ppce['xgen'].shape) tmp[2, :] = ppce['xgen'][2, :] got = i2e_data(ppc, ex, tmp, 'gen') t_is(got, ppce['xgen'], 12, t) t = 'val = e2i_data(ppc, val, \'gen\', 1)' got = e2i_data(ppc, ppce['xgen'], 'gen', 1) ex = ppce['xgen'][:, [3, 1, 0]] t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, \'gen\', 1)' tmp = ones(ppce['xgen'].shape) tmp[:, 2] = ppce['xgen'][:, 2] got = i2e_data(ppc, ex, tmp, 'gen', 1) t_is(got, ppce['xgen'], 12, t) t = 'val = e2i_data(ppc, val, \'branch\')' got = e2i_data(ppc, ppce['xbranch'], 'branch') ex = ppce['xbranch'] ex = delete(ex, 6, 0) t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, \'branch\')' tmp = ones(ppce['xbranch'].shape) tmp[6, :] = ppce['xbranch'][6, :] got = i2e_data(ppc, ex, tmp, 'branch') t_is(got, ppce['xbranch'], 12, t) t = 'val = e2i_data(ppc, val, \'branch\', 1)' got = e2i_data(ppc, ppce['xbranch'], 'branch', 1) ex = ppce['xbranch'] ex = delete(ex, 6, 1) t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, \'branch\', 1)' tmp = ones(ppce['xbranch'].shape) tmp[:, 6] = ppce['xbranch'][:, 6] got = i2e_data(ppc, ex, tmp, 'branch', 1) t_is(got, ppce['xbranch'], 12, t) t = 'val = e2i_data(ppc, val, {\'branch\', \'gen\', \'bus\'})' got = e2i_data(ppc, ppce['xrows'], ['branch', 'gen', 'bus']) ex = r_[ppce['xbranch'][list(range(6)) + list(range(7, 10)), :4], ppce['xgen'][[3, 1, 0], :], ppce['xbus'][list(range(5)) + list(range(6, 10)), :4], -1 * ones((2, 4))] t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, {\'branch\', \'gen\', \'bus\'})' tmp1 = ones(ppce['xbranch'][:, :4].shape) tmp1[6, :4] = ppce['xbranch'][6, :4] tmp2 = ones(ppce['xgen'].shape) tmp2[2, :] = ppce['xgen'][2, :] tmp3 = ones(ppce['xbus'][:, :4].shape) tmp3[5, :4] = ppce['xbus'][5, :4] tmp = r_[tmp1, tmp2, tmp3] got = i2e_data(ppc, ex, tmp, ['branch', 'gen', 'bus']) t_is(got, ppce['xrows'], 12, t) t = 'val = e2i_data(ppc, val, {\'branch\', \'gen\', \'bus\'}, 1)' got = e2i_data(ppc, ppce['xcols'], ['branch', 'gen', 'bus'], 1) ex = r_[ppce['xbranch'][list(range(6)) + list(range(7, 10)), :4], ppce['xgen'][[3, 1, 0], :], ppce['xbus'][list(range(5)) + list(range(6, 10)), :4], -1 * ones((2, 4))].T t_is(got, ex, 12, t) t = 'val = i2e_data(ppc, val, oldval, {\'branch\', \'gen\', \'bus\'}, 1)' tmp1 = ones(ppce['xbranch'][:, :4].shape) tmp1[6, :4] = ppce['xbranch'][6, :4] tmp2 = ones(ppce['xgen'].shape) tmp2[2, :] = ppce['xgen'][2, :] tmp3 = ones(ppce['xbus'][:, :4].shape) tmp3[5, :4] = ppce['xbus'][5, :4] tmp = r_[tmp1, tmp2, tmp3].T got = i2e_data(ppc, ex, tmp, ['branch', 'gen', 'bus'], 1) t_is(got, ppce['xcols'], 12, t) ##----- ppc = e2i_field/i2e_field(ppc, field, ...) ----- t = 'ppc = e2i_field(ppc, field, \'bus\')' ppc = e2i_field(ppce) ex = ppce['xbus'] ex = delete(ex, 5, 0) got = e2i_field(ppc, 'xbus', 'bus') t_is(got['xbus'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, \'bus\')' got = i2e_field(got, 'xbus', ordering='bus') t_is(got['xbus'], ppce['xbus'], 12, t) t = 'ppc = e2i_field(ppc, field, \'bus\', 1)' ex = ppce['xbus'] ex = delete(ex, 5, 1) got = e2i_field(ppc, 'xbus', 'bus', 1) t_is(got['xbus'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, \'bus\', 1)' got = i2e_field(got, 'xbus', ordering='bus', dim=1) t_is(got['xbus'], ppce['xbus'], 12, t) t = 'ppc = e2i_field(ppc, field, \'gen\')' ex = ppce['xgen'][[3, 1, 0], :] got = e2i_field(ppc, 'xgen', 'gen') t_is(got['xgen'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, \'gen\')' got = i2e_field(got, 'xgen', ordering='gen') t_is(got['xgen'], ppce['xgen'], 12, t) t = 'ppc = e2i_field(ppc, field, \'gen\', 1)' ex = ppce['xgen'][:, [3, 1, 0]] got = e2i_field(ppc, 'xgen', 'gen', 1) t_is(got['xgen'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, \'gen\', 1)' got = i2e_field(got, 'xgen', ordering='gen', dim=1) t_is(got['xgen'], ppce['xgen'], 12, t) t = 'ppc = e2i_field(ppc, field, \'branch\')' ex = ppce['xbranch'] ex = delete(ex, 6, 0) got = e2i_field(ppc, 'xbranch', 'branch') t_is(got['xbranch'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, \'branch\')' got = i2e_field(got, 'xbranch', ordering='branch') t_is(got['xbranch'], ppce['xbranch'], 12, t) t = 'ppc = e2i_field(ppc, field, \'branch\', 1)' ex = ppce['xbranch'] ex = delete(ex, 6, 1) got = e2i_field(ppc, 'xbranch', 'branch', 1) t_is(got['xbranch'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, \'branch\', 1)' got = i2e_field(got, 'xbranch', ordering='branch', dim=1) t_is(got['xbranch'], ppce['xbranch'], 12, t) t = 'ppc = e2i_field(ppc, field, {\'branch\', \'gen\', \'bus\'})' ex = r_[ppce['xbranch'][list(range(6)) + list(range(7, 10)), :4], ppce['xgen'][[3, 1, 0], :], ppce['xbus'][list(range(5)) + list(range(6, 10)), :4], -1 * ones((2, 4))] got = e2i_field(ppc, 'xrows', ['branch', 'gen', 'bus']) t_is(got['xrows'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, {\'branch\', \'gen\', \'bus\'})' got = i2e_field(got, 'xrows', ordering=['branch', 'gen', 'bus']) t_is(got['xrows'], ppce['xrows'], 12, t) t = 'ppc = e2i_field(ppc, field, {\'branch\', \'gen\', \'bus\'}, 1)' ex = r_[ppce['xbranch'][list(range(6)) + list(range(7, 10)), :4], ppce['xgen'][[3, 1, 0], :], ppce['xbus'][list(range(5)) + list(range(6, 10)), :4], -1 * ones((2, 4))].T got = e2i_field(ppc, 'xcols', ['branch', 'gen', 'bus'], 1) t_is(got['xcols'], ex, 12, t) t = 'ppc = i2e_field(ppc, field, {\'branch\', \'gen\', \'bus\'})' got = i2e_field(got, 'xcols', ordering=['branch', 'gen', 'bus'], dim=1) t_is(got['xcols'], ppce['xcols'], 12, t) t = 'ppc = e2i_field(ppc, {\'field1\', \'field2\'}, ordering)' ex = ppce['x']['more'][[3, 1, 0], :] got = e2i_field(ppc, ['x', 'more'], 'gen') t_is(got['x']['more'], ex, 12, t) t = 'ppc = i2e_field(ppc, {\'field1\', \'field2\'}, ordering)' got = i2e_field(got, ['x', 'more'], ordering='gen') t_is(got['x']['more'], ppce['x']['more'], 12, t) t = 'ppc = e2i_field(ppc, {\'field1\', \'field2\'}, ordering, 1)' ex = ppce['x']['more'][:, [3, 1, 0]] got = e2i_field(ppc, ['x', 'more'], 'gen', 1) t_is(got['x']['more'], ex, 12, t) t = 'ppc = i2e_field(ppc, {\'field1\', \'field2\'}, ordering, 1)' got = i2e_field(got, ['x', 'more'], ordering='gen', dim=1) t_is(got['x']['more'], ppce['x']['more'], 12, t) ##----- more ppc = ext2int/int2ext(ppc) ----- t = 'ppc = ext2int(ppc) - bus/gen/branch only : ' ppce = loadcase(t_case_ext()) ppci = loadcase(t_case_int()) del ppce['gencost'] del ppce['areas'] del ppce['A'] del ppce['N'] del ppci['gencost'] del ppci['areas'] del ppci['A'] del ppci['N'] ppc = ext2int(ppce) t_is(ppc['bus'], ppci['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppci['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppci['gen'], 12, [t, 'gen']) t = 'ppc = ext2int(ppc) - no areas/A : ' ppce = loadcase(t_case_ext()) ppci = loadcase(t_case_int()) del ppce['areas'] del ppce['A'] del ppci['areas'] del ppci['A'] ppc = ext2int(ppce) t_is(ppc['bus'], ppci['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppci['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppci['gen'], 12, [t, 'gen']) t_is(ppc['gencost'], ppci['gencost'], 12, [t, 'gencost']) t_is(ppc['N'], ppci['N'], 12, [t, 'N']) t = 'ppc = ext2int(ppc) - Qg cost, no N : ' ppce = loadcase(t_case_ext()) ppci = loadcase(t_case_int()) del ppce['N'] del ppci['N'] ppce['gencost'] = c_[ppce['gencost'], ppce['gencost']] ppci['gencost'] = c_[ppci['gencost'], ppci['gencost']] ppc = ext2int(ppce) t_is(ppc['bus'], ppci['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppci['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppci['gen'], 12, [t, 'gen']) t_is(ppc['gencost'], ppci['gencost'], 12, [t, 'gencost']) t_is(ppc['areas'], ppci['areas'], 12, [t, 'areas']) t_is(ppc['A'], ppci['A'], 12, [t, 'A']) t = 'ppc = ext2int(ppc) - A, N are DC sized : ' ppce = loadcase(t_case_ext()) ppci = loadcase(t_case_int()) eVmQgcols = list(range(10, 20)) + list(range(24, 28)) iVmQgcols = list(range(9, 18)) + list(range(21, 24)) ppce['A'] = delete(ppce['A'], eVmQgcols, 1) ppce['N'] = delete(ppce['N'], eVmQgcols, 1) ppci['A'] = delete(ppci['A'], iVmQgcols, 1) ppci['N'] = delete(ppci['N'], iVmQgcols, 1) ppc = ext2int(ppce) t_is(ppc['bus'], ppci['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppci['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppci['gen'], 12, [t, 'gen']) t_is(ppc['gencost'], ppci['gencost'], 12, [t, 'gencost']) t_is(ppc['areas'], ppci['areas'], 12, [t, 'areas']) t_is(ppc['A'], ppci['A'], 12, [t, 'A']) t_is(ppc['N'], ppci['N'], 12, [t, 'N']) t = 'ppc = int2ext(ppc) - A, N are DC sized : ' ppc = int2ext(ppc) t_is(ppc['bus'], ppce['bus'], 12, [t, 'bus']) t_is(ppc['branch'], ppce['branch'], 12, [t, 'branch']) t_is(ppc['gen'], ppce['gen'], 12, [t, 'gen']) t_is(ppc['gencost'], ppce['gencost'], 12, [t, 'gencost']) t_is(ppc['areas'], ppce['areas'], 12, [t, 'areas']) t_is(ppc['A'], ppce['A'], 12, [t, 'A']) t_is(ppc['N'], ppce['N'], 12, [t, 'N']) t_end()
def runcpf(basecasedata=None, targetcasedata=None, ppopt=None, fname='', solvedcase=''): # default arguments if basecasedata is None: basecasedata = join(dirname(__file__), 'case9') if targetcasedata is None: targetcasedata = join(dirname(__file__), 'case9target') ppopt = ppoption(ppopt) # options verbose = ppopt["VERBOSE"] step = ppopt["CPF_STEP"] parameterization = ppopt["CPF_PARAMETERIZATION"] adapt_step = ppopt["CPF_ADAPT_STEP"] cb_args = ppopt["CPF_USER_CALLBACK_ARGS"] # set up callbacks callback_names = ["cpf_default_callback"] if len(ppopt["CPF_USER_CALLBACK"]) > 0: if isinstance(ppopt["CPF_USER_CALLBACK"], list): callback_names = r_[callback_names, ppopt["CPF_USER_CALLBACK"]] else: callback_names.append(ppopt["CPF_USER_CALLBACK"]) callbacks = [] for callback_name in callback_names: callbacks.append(getattr(cpf_callbacks, callback_name)) # read base case data ppcbase = loadcase(basecasedata) nb = ppcbase["bus"].shape[0] # add zero columns to branch for flows if needed if ppcbase["branch"].shape[1] < QT: ppcbase["branch"] = c_[ppcbase["branch"], zeros((ppcbase["branch"].shape[0], QT - ppcbase["branch"].shape[1] + 1))] # convert to internal indexing ppcbase = ext2int(ppcbase) baseMVAb, busb, genb, branchb = \ ppcbase["baseMVA"], ppcbase["bus"], ppcbase["gen"], ppcbase["branch"] # get bus index lists of each type of bus ref, pv, pq = bustypes(busb, genb) # generator info onb = find(genb[:, GEN_STATUS] > 0) # which generators are on? gbusb = genb[onb, GEN_BUS].astype(int) # what buses are they at? # read target case data ppctarget = loadcase(targetcasedata) # add zero columns to branch for flows if needed if ppctarget["branch"].shape[1] < QT: ppctarget["branch"] = c_[ppctarget["branch"], zeros( (ppctarget["branch"].shape[0], QT - ppctarget["branch"].shape[1] + 1))] # convert to internal indexing ppctarget = ext2int(ppctarget) baseMVAt, bust, gent, brancht = \ ppctarget["baseMVA"], ppctarget["bus"], ppctarget["gen"], ppctarget["branch"] # get bus index lists of each type of bus # ref, pv, pq = bustypes(bust, gent) # generator info ont = find(gent[:, GEN_STATUS] > 0) # which generators are on? gbust = gent[ont, GEN_BUS].astype(int) # what buses are they at? # ----- run the power flow ----- t0 = time() if verbose > 0: v = ppver('all') stdout.write('PYPOWER Version %s, %s' % (v["Version"], v["Date"])) stdout.write(' -- AC Continuation Power Flow\n') # initial state # V0 = ones(bus.shape[0]) ## flat start V0 = busb[:, VM] * exp(1j * pi / 180 * busb[:, VA]) vcb = ones(V0.shape) # create mask of voltage-controlled buses vcb[pq] = 0 # exclude PQ buses k = find(vcb[gbusb]) # in-service gens at v-c buses V0[gbusb[k]] = genb[onb[k], VG] / abs(V0[gbusb[k]]) * V0[gbusb[k]] # build admittance matrices Ybus, Yf, Yt = makeYbus(baseMVAb, busb, branchb) # compute base case complex bus power injections (generation - load) Sbusb = makeSbus(baseMVAb, busb, genb) # compute target case complex bus power injections (generation - load) Sbust = makeSbus(baseMVAt, bust, gent) # scheduled transfer Sxfr = Sbust - Sbusb # Run the base case power flow solution if verbose > 2: ppopt_pf = ppoption(ppopt, VERBOSE=max(0, verbose - 1)) else: ppopt_pf = ppoption(ppopt, VERBOSE=max(0, verbose - 2)) lam = 0 V, success, iterations = newtonpf(Ybus, Sbusb, V0, ref, pv, pq, ppopt_pf) if verbose > 2: print('step %3d : lambda = %6.3f\n' % (0, 0)) elif verbose > 1: print('step %3d : lambda = %6.3f, %2d Newton steps\n', (0, 0, iterations)) lamprv = lam # lam at previous step Vprv = V # V at previous step continuation = 1 cont_steps = 0 # input args for callbacks cb_data = { "ppc_base": ppcbase, "ppc_target": ppctarget, "Sxfr": Sxfr, "Ybus": Ybus, "Yf": Yf, "Yt": Yt, "ref": ref, "pv": pv, "pq": pq, "ppopt": ppopt } cb_state = {} # invoke callbacks for k in range(len(callbacks)): cb_state, _ = callbacks[k](cont_steps, V, lam, V, lam, cb_data, cb_state, cb_args) if linalg.norm(Sxfr) == 0: if verbose: print( 'base case and target case have identical load and generation\n' ) continuation = 0 V0 = V lam0 = lam # tangent predictor z = [dx;dlam] z = zeros(2 * len(V) + 1) z[-1] = 1.0 while continuation: cont_steps = cont_steps + 1 # prediction for next step V0, lam0, z = cpf_predictor(V, lam, Ybus, Sxfr, pv, pq, step, z, Vprv, lamprv, parameterization) # save previous voltage, lambda before updating Vprv = V lamprv = lam # correction V, success, i, lam = cpf_corrector(Ybus, Sbusb, V0, ref, pv, pq, lam0, Sxfr, Vprv, lamprv, z, step, parameterization, ppopt_pf) if not success: continuation = 0 if verbose: print( 'step %3d : lambda = %6.3f, corrector did not converge in %d iterations\n' % (cont_steps, lam, i)) break if verbose > 2: print('step %3d : lambda = %6.3f\n' % (cont_steps, lam)) elif verbose > 1: print('step %3d : lambda = %6.3f, %2d corrector Newton steps\n' % (cont_steps, lam, i)) # invoke callbacks for k in range(len(callbacks)): cb_state, _ = callbacks[k](cont_steps, V, lam, V0, lam0, cb_data, cb_state, cb_args) if isinstance(ppopt["CPF_STOP_AT"], str): if ppopt["CPF_STOP_AT"].upper() == "FULL": if abs(lam) < 1e-8: # traced the full continuation curve if verbose: print( '\nTraced full continuation curve in %d continuation steps\n' % cont_steps) continuation = 0 elif lam < lamprv and lam - step < 0: # next step will overshoot step = lam # modify step-size parameterization = 1 # change to natural parameterization adapt_step = False # disable step-adaptivity else: # == 'NOSE' if lam < lamprv: # reached the nose point if verbose: print( '\nReached steady state loading limit in %d continuation steps\n' % cont_steps) continuation = 0 else: if lam < lamprv: if verbose: print( '\nReached steady state loading limit in %d continuation steps\n' % cont_steps) continuation = 0 elif abs(ppopt["CPF_STOP_AT"] - lam) < 1e-8: # reached desired lambda if verbose: print( '\nReached desired lambda %3.2f in %d continuation steps\n' % (ppopt["CPF_STOP_AT"], cont_steps)) continuation = 0 # will reach desired lambda in next step elif lam + step > ppopt["CPF_STOP_AT"]: step = ppopt["CPF_STOP_AT"] - lam # modify step-size parameterization = 1 # change to natural parameterization adapt_step = False # disable step-adaptivity if adapt_step and continuation: pvpq = r_[pv, pq] # Adapt stepsize cpf_error = linalg.norm( r_[angle(V[pq]), abs(V[pvpq]), lam] - r_[angle(V0[pq]), abs(V0[pvpq]), lam0], inf) if cpf_error < ppopt["CPF_ERROR_TOL"]: # Increase stepsize step = step * ppopt["CPF_ERROR_TOL"] / cpf_error if step > ppopt["CPF_STEP_MAX"]: step = ppopt["CPF_STEP_MAX"] else: # decrese stepsize step = step * ppopt["CPF_ERROR_TOL"] / cpf_error if step < ppopt["CPF_STEP_MIN"]: step = ppopt["CPF_STEP_MIN"] # invoke callbacks if success: cpf_results = {} for k in range(len(callbacks)): cb_state, cpf_results = callbacks[k](cont_steps, V, lam, V0, lam0, cb_data, cb_state, cb_args, results=cpf_results, is_final=True) else: cpf_results["iterations"] = i # update bus and gen matrices to reflect the loading and generation # at the noise point bust[:, PD] = busb[:, PD] + lam * (bust[:, PD] - busb[:, PD]) bust[:, QD] = busb[:, QD] + lam * (bust[:, QD] - busb[:, QD]) gent[:, PG] = genb[:, PG] + lam * (gent[:, PG] - genb[:, PG]) # update data matrices with solution bust, gent, brancht = pfsoln(baseMVAt, bust, gent, brancht, Ybus, Yf, Yt, V, ref, pv, pq) ppctarget["et"] = time() - t0 ppctarget["success"] = success # ----- output results ----- # convert back to original bus numbering & print results ppctarget["bus"], ppctarget["gen"], ppctarget[ "branch"] = bust, gent, brancht if success: n = cpf_results["iterations"] + 1 cpf_results["V_p"] = i2e_data(ppctarget, cpf_results["V_p"], full((nb, n), nan), "bus", 0) cpf_results["V_c"] = i2e_data(ppctarget, cpf_results["V_c"], full((nb, n), nan), "bus", 0) results = int2ext(ppctarget) results["cpf"] = cpf_results # zero out result fields of out-of-service gens & branches if len(results["order"]["gen"]["status"]["off"]) > 0: results["gen"][ix_(results["order"]["gen"]["status"]["off"], [PG, QG])] = 0 if len(results["order"]["branch"]["status"]["off"]) > 0: results["branch"][ix_(results["order"]["branch"]["status"]["off"], [PF, QF, PT, QT])] = 0 if fname: fd = None try: fd = open(fname, "a") except Exception as detail: stderr.write("Error opening %s: %s.\n" % (fname, detail)) finally: if fd is not None: printpf(results, fd, ppopt) fd.close() else: printpf(results, stdout, ppopt) # save solved case if solvedcase: savecase(solvedcase, results) return results, success
def userfcn_reserves_int2ext(results, *args): """This is the 'int2ext' stage userfcn callback that converts everything back to external indexing and packages up the results. It expects to find a 'reserves' field in the results struct as described for ppc above, including the two additional fields 'igr' and 'rgens'. It also expects the results to contain a variable 'R' and linear constraints 'Pg_plus_R' and 'Rreq' which are used to populate output fields in results.reserves. The optional args are not currently used. """ ## initialize some things r = results['reserves'] ## grab some info in internal indexing order igr = r['igr'] ## indices of gens available to provide reserves ng = results['gen'].shape[0] ## number of on-line gens (+ disp loads) ##----- convert stuff back to external indexing ----- ## convert all reserve parameters (zones, costs, qty, rgens) if 'qty' in r: results = i2e_field(results, ['reserves', 'qty'], ordering='gen') results = i2e_field(results, ['reserves', 'cost'], ordering='gen') results = i2e_field(results, ['reserves', 'zones'], ordering='gen', dim=1) results = i2e_field(results, ['reserves', 'rgens'], ordering='gen', dim=1) results['order']['int']['reserves']['igr'] = results['reserves'][ 'igr'] ## save internal version results['reserves']['igr'] = results['order']['ext']['reserves'][ 'igr'] ## use external version r = results['reserves'] ## update o = results['order'] ## update ## grab same info in external indexing order igr0 = r['igr'] ## indices of gens available to provide reserves ng0 = o['ext']['gen'].shape[0] ## number of gens (+ disp loads) ##----- results post-processing ----- ## get the results (per gen reserves, multipliers) with internal gen indexing ## and convert from p.u. to per MW units _, Rl, Ru = results['om'].getv('R') R = zeros(ng) Rmin = zeros(ng) Rmax = zeros(ng) mu_l = zeros(ng) mu_u = zeros(ng) mu_Pmax = zeros(ng) R[igr] = results['var']['val']['R'] * results['baseMVA'] Rmin[igr] = Rl * results['baseMVA'] Rmax[igr] = Ru * results['baseMVA'] mu_l[igr] = results['var']['mu']['l']['R'] / results['baseMVA'] mu_u[igr] = results['var']['mu']['u']['R'] / results['baseMVA'] mu_Pmax[igr] = results['lin']['mu']['u']['Pg_plus_R'] / results['baseMVA'] ## store in results in results struct z = zeros(ng0) results['reserves']['R'] = i2e_data(results, R, z, 'gen') results['reserves']['Rmin'] = i2e_data(results, Rmin, z, 'gen') results['reserves']['Rmax'] = i2e_data(results, Rmax, z, 'gen') if 'mu' not in results['reserves']: results['reserves']['mu'] = {} results['reserves']['mu']['l'] = i2e_data(results, mu_l, z, 'gen') results['reserves']['mu']['u'] = i2e_data(results, mu_u, z, 'gen') results['reserves']['mu']['Pmax'] = i2e_data(results, mu_Pmax, z, 'gen') results['reserves']['prc'] = z for k in igr0: iz = find(r['zones'][:, k]) results['reserves']['prc'][k] = sum( results['lin']['mu']['l']['Rreq'][iz]) / results['baseMVA'] results['reserves']['totalcost'] = results['cost']['Rcost'] ## replace ng x 1 cost, qty with ngr x 1 originals if 'original' in r: if 'qty' in r: results['reserves']['qty'] = r['original']['qty'] results['reserves']['cost'] = r['original']['cost'] del results['reserves']['original'] return results
def userfcn_reserves_int2ext(results, *args): """This is the 'int2ext' stage userfcn callback that converts everything back to external indexing and packages up the results. It expects to find a 'reserves' field in the results struct as described for ppc above, including the two additional fields 'igr' and 'rgens'. It also expects the results to contain a variable 'R' and linear constraints 'Pg_plus_R' and 'Rreq' which are used to populate output fields in results.reserves. The optional args are not currently used. """ ## initialize some things r = results['reserves'] ## grab some info in internal indexing order igr = r['igr'] ## indices of gens available to provide reserves ng = results['gen'].shape[0] ## number of on-line gens (+ disp loads) ##----- convert stuff back to external indexing ----- ## convert all reserve parameters (zones, costs, qty, rgens) if 'qty' in r: results = i2e_field(results, ['reserves', 'qty'], ordering='gen') results = i2e_field(results, ['reserves', 'cost'], ordering='gen') results = i2e_field(results, ['reserves', 'zones'], ordering='gen', dim=1) results = i2e_field(results, ['reserves', 'rgens'], ordering='gen', dim=1) results['order']['int']['reserves']['igr'] = results['reserves']['igr'] ## save internal version results['reserves']['igr'] = results['order']['ext']['reserves']['igr'] ## use external version r = results['reserves'] ## update o = results['order'] ## update ## grab same info in external indexing order igr0 = r['igr'] ## indices of gens available to provide reserves ng0 = o['ext']['gen'].shape[0] ## number of gens (+ disp loads) ##----- results post-processing ----- ## get the results (per gen reserves, multipliers) with internal gen indexing ## and convert from p.u. to per MW units _, Rl, Ru = results['om'].getv('R') R = zeros(ng) Rmin = zeros(ng) Rmax = zeros(ng) mu_l = zeros(ng) mu_u = zeros(ng) mu_Pmax = zeros(ng) R[igr] = results['var']['val']['R'] * results['baseMVA'] Rmin[igr] = Rl * results['baseMVA'] Rmax[igr] = Ru * results['baseMVA'] mu_l[igr] = results['var']['mu']['l']['R'] / results['baseMVA'] mu_u[igr] = results['var']['mu']['u']['R'] / results['baseMVA'] mu_Pmax[igr] = results['lin']['mu']['u']['Pg_plus_R'] / results['baseMVA'] ## store in results in results struct z = zeros(ng0) results['reserves']['R'] = i2e_data(results, R, z, 'gen') results['reserves']['Rmin'] = i2e_data(results, Rmin, z, 'gen') results['reserves']['Rmax'] = i2e_data(results, Rmax, z, 'gen') if 'mu' not in results['reserves']: results['reserves']['mu'] = {} results['reserves']['mu']['l'] = i2e_data(results, mu_l, z, 'gen') results['reserves']['mu']['u'] = i2e_data(results, mu_u, z, 'gen') results['reserves']['mu']['Pmax'] = i2e_data(results, mu_Pmax, z, 'gen') results['reserves']['prc'] = z for k in igr0: iz = find(r['zones'][:, k]) results['reserves']['prc'][k] = sum(results['lin']['mu']['l']['Rreq'][iz]) / results['baseMVA'] results['reserves']['totalcost'] = results['cost']['Rcost'] ## replace ng x 1 cost, qty with ngr x 1 originals if 'original' in r: if 'qty' in r: results['reserves']['qty'] = r['original']['qty'] results['reserves']['cost'] = r['original']['cost'] del results['reserves']['original'] return results
def int2ext(ppc, val_or_field=None, oldval=None, ordering=None, dim=0): """Converts internal to external bus numbering. C{ppc = int2ext(ppc)} If the input is a single PYPOWER case dict, then it restores all buses, generators and branches that were removed because of being isolated or off-line, and reverts to the original generator ordering and original bus numbering. This requires that the 'order' key created by L{ext2int} be in place. Example:: ppc = int2ext(ppc) @see: L{ext2int}, L{i2e_field}, L{i2e_data} @author: Ray Zimmerman (PSERC Cornell) """ ppc = deepcopy(ppc) if val_or_field is None: # nargin == 1 if 'order' not in ppc: sys.stderr.write('int2ext: ppc does not have the "order" field ' 'required for conversion back to external numbering.\n') o = ppc["order"] if o["state"] == 'i': ## execute userfcn callbacks for 'int2ext' stage if 'userfcn' in ppc: ppc = run_userfcn(ppc["userfcn"], 'int2ext', ppc) ## save data matrices with internal ordering & restore originals o["int"] = {} o["int"]["bus"] = ppc["bus"].copy() o["int"]["branch"] = ppc["branch"].copy() o["int"]["gen"] = ppc["gen"].copy() ppc["bus"] = o["ext"]["bus"].copy() ppc["branch"] = o["ext"]["branch"].copy() ppc["gen"] = o["ext"]["gen"].copy() if 'gencost' in ppc: o["int"]["gencost"] = ppc["gencost"].copy() ppc["gencost"] = o["ext"]["gencost"].copy() if 'areas' in ppc: o["int"]["areas"] = ppc["areas"].copy() ppc["areas"] = o["ext"]["areas"].copy() if 'A' in ppc: o["int"]["A"] = ppc["A"].copy() ppc["A"] = o["ext"]["A"].copy() if 'N' in ppc: o["int"]["N"] = ppc["N"].copy() ppc["N"] = o["ext"]["N"].copy() ## update data (in bus, branch and gen only) ppc["bus"][o["bus"]["status"]["on"], :] = \ o["int"]["bus"] ppc["branch"][o["branch"]["status"]["on"], :] = \ o["int"]["branch"] ppc["gen"][o["gen"]["status"]["on"], :] = \ o["int"]["gen"][o["gen"]["i2e"], :] if 'areas' in ppc: ppc["areas"][o["areas"]["status"]["on"], :] = \ o["int"]["areas"] ## revert to original bus numbers ppc["bus"][o["bus"]["status"]["on"], BUS_I] = \ o["bus"]["i2e"] \ [ ppc["bus"][o["bus"]["status"]["on"], BUS_I].astype(int) ] ppc["branch"][o["branch"]["status"]["on"], F_BUS] = \ o["bus"]["i2e"][ ppc["branch"] \ [o["branch"]["status"]["on"], F_BUS].astype(int) ] ppc["branch"][o["branch"]["status"]["on"], T_BUS] = \ o["bus"]["i2e"][ ppc["branch"] \ [o["branch"]["status"]["on"], T_BUS].astype(int) ] ppc["gen"][o["gen"]["status"]["on"], GEN_BUS] = \ o["bus"]["i2e"][ ppc["gen"] \ [o["gen"]["status"]["on"], GEN_BUS].astype(int) ] if 'areas' in ppc: ppc["areas"][o["areas"]["status"]["on"], PRICE_REF_BUS] = \ o["bus"]["i2e"][ ppc["areas"] \ [o["areas"]["status"]["on"], PRICE_REF_BUS].astype(int) ] if 'ext' in o: del o['ext'] o["state"] = 'e' ppc["order"] = o else: sys.stderr.write('int2ext: ppc claims it is already using ' 'external numbering.\n') else: ## convert extra data if isinstance(val_or_field, str) or isinstance(val_or_field, list): ## field (key) warn('Calls of the form MPC = INT2EXT(MPC, ''FIELD_NAME'', ...) have been deprecated. Please replace INT2EXT with I2E_FIELD.') bus, gen = val_or_field, oldval if ordering is not None: dim = ordering ppc = i2e_field(ppc, bus, gen, dim) else: ## value warn('Calls of the form VAL = INT2EXT(MPC, VAL, ...) have been deprecated. Please replace INT2EXT with I2E_DATA.') bus, gen, branch = val_or_field, oldval, ordering ppc = i2e_data(ppc, bus, gen, branch, dim) return ppc