0001 function [nx, cx, done, rollback, evnts, cb_data, results] = cpf_plim_event_cb(...
0002 k, nx, cx, px, done, rollback, evnts, cb_data, cb_args, results)
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 if k <= 0 || done.flag
0031 return;
0032 end
0033
0034
0035 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0036 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0037 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0038 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0039 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0040
0041 mpc = [];
0042
0043
0044 for i = 1:length(evnts)
0045 if strcmp(evnts(i).name, 'PLIM') && evnts(i).zero
0046
0047 if isempty(mpc)
0048 d = cb_data;
0049 if length(d.ref) ~= 1
0050 error('cpf_plim_event_cb: ''cpf.enforce_plims'' option only valid for systems with exactly one REF bus')
0051 end
0052 mpc = cpf_current_mpc(d.mpc_base, d.mpc_target, ...
0053 d.Ybus, d.Yf, d.Yt, d.ref, d.pv, d.pq, nx.V, nx.lam, d.mpopt);
0054 ng = size(mpc.gen, 1);
0055 i2e_bus = cb_data.mpc_target.order.bus.i2e;
0056 i2e_gen = cb_data.mpc_target.order.gen.i2e;
0057 end
0058
0059
0060 if cb_data.mpopt.verbose > 3
0061 msg = sprintf('%s\n ', evnts(i).msg);
0062 else
0063 msg = '';
0064 end
0065 ig = evnts(i).idx;
0066 for j = 1:length(ig)
0067 g = ig(j);
0068 ib = mpc.gen(g, GEN_BUS);
0069 msg = sprintf('%sgen %d @ bus %d reached %g MW Pmax lim @ lambda = %.4g', ...
0070 msg, i2e_gen(g), i2e_bus(ib), mpc.gen(g, PMAX), nx.lam);
0071 if ib == cb_data.ref
0072
0073 idx_pmax = find( mpc.gen(:, GEN_STATUS) > 0 & ...
0074 abs(mpc.gen(:, PG) - mpc.gen(:, PMAX)) < d.mpopt.cpf.p_lims_tol );
0075
0076
0077 candidates = zeros(size(mpc.bus, 1), 1);
0078 candidates(cb_data.pv) = 1;
0079 candidates(mpc.gen(idx_pmax, GEN_BUS)) = 0;
0080 candidates(ib) = 0;
0081 new_ref = find(candidates, 1);
0082 if isempty(new_ref)
0083 done.flag = 1;
0084 done.msg = 'All generators at Pmax';
0085 else
0086
0087 mpc.bus(ib, BUS_TYPE) = PV;
0088 mpc.bus(new_ref, BUS_TYPE) = REF;
0089
0090
0091 [ref, pv, pq] = bustypes(mpc.bus, mpc.gen);
0092 msg = sprintf('%s : ref changed from bus %d to %d', ...
0093 msg, i2e_bus(ib), i2e_bus(new_ref));
0094 end
0095 end
0096
0097
0098 mpc.gen(g, PG) = mpc.gen(g, PMAX);
0099
0100
0101 if ib == cb_data.ref && ~isempty(new_ref)
0102 cb_data.ref = ref;
0103 cb_data.pv = pv;
0104 cb_data.pq = pq;
0105 cb_data.mpc_base.bus( ib, BUS_TYPE) = mpc.bus(ib, BUS_TYPE);
0106 cb_data.mpc_target.bus(ib, BUS_TYPE) = mpc.bus(ib, BUS_TYPE);
0107 cb_data.mpc_base.bus( new_ref, BUS_TYPE) = mpc.bus(new_ref, BUS_TYPE);
0108 cb_data.mpc_target.bus(new_ref, BUS_TYPE) = mpc.bus(new_ref, BUS_TYPE);
0109 end
0110
0111
0112
0113 cb_data.mpc_base.gen( g, PG) = mpc.gen(g, PG);
0114 cb_data.mpc_target.gen(g, PG) = mpc.gen(g, PG);
0115 cb_data.idx_pmax = [cb_data.idx_pmax; g];
0116
0117
0118 b = cb_data.mpc_base;
0119 t = cb_data.mpc_target;
0120 cb_data.Sbusb = @(Vm)makeSbus(b.baseMVA, b.bus, b.gen, d.mpopt, Vm);
0121 cb_data.Sbust = @(Vm)makeSbus(t.baseMVA, t.bus, t.gen, d.mpopt, Vm);
0122
0123
0124 nx.this_step = 0;
0125 end
0126 evnts(i).msg = msg;
0127 end
0128 end