0001 function [mpc, warns] = psse_convert(warns, data, verbose)
0002
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
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0055 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0056 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0057 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0058 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0059 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0060 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0061 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0062
0063
0064 sort_buses = 1;
0065
0066
0067 if nargin < 3
0068 verbose = 0;
0069 end
0070 haveVlims = 0;
0071 Vmin = 0.9;
0072 Vmax = 1.1;
0073
0074
0075 baseMVA = data.id.SBASE;
0076 rev = data.id.REV;
0077
0078
0079 numbus = data.bus.num;
0080 [nb, ncols] = size(numbus);
0081 bus = zeros(nb, VMIN);
0082 if rev < 24
0083 bus_name_col = 10;
0084 else
0085 bus_name_col = 2;
0086 end
0087 if sort_buses
0088 [numbus, i] = sortrows(numbus, 1);
0089 bus_name = data.bus.txt(i, bus_name_col);
0090 else
0091 bus_name = data.bus.txt(:, bus_name_col);
0092 end
0093 if rev < 24
0094 bus(:, [BUS_I BUS_TYPE PD QD GS BS BUS_AREA VM VA BASE_KV ZONE]) = ...
0095 numbus(:, [1:9 11:12]);
0096 elseif rev < 31
0097 bus(:, [BUS_I BASE_KV BUS_TYPE GS BS BUS_AREA ZONE VM VA]) = ...
0098 numbus(:, [1 3 4 5 6 7 8 9 10]);
0099 else
0100 bus(:, [BUS_I BASE_KV BUS_TYPE BUS_AREA ZONE VM VA]) = ...
0101 numbus(:, [1 3 4 5 6 8 9]);
0102 if ncols >= 11 && all(all(~isnan(numbus(:, [10 11]))))
0103 haveVlims = 1;
0104 bus(:, [VMAX VMIN]) = numbus(:, [10 11]);
0105 end
0106 end
0107 if ~haveVlims
0108 warns{end+1} = sprintf('Using default voltage magnitude limits: VMIN = %g p.u., VMAX = %g p.u.', Vmin, Vmax);
0109 if verbose
0110 fprintf('WARNING: No bus voltage magnitude limits provided.\n Using defaults: VMIN = %g p.u., VMAX = %g p.u.\n', Vmin, Vmax);
0111 end
0112 bus(:, VMIN) = Vmin;
0113 bus(:, VMAX) = Vmax;
0114 end
0115
0116
0117 i2e = bus(:, BUS_I);
0118 e2i = sparse(i2e, ones(nb, 1), 1:nb, max(i2e), 1);
0119
0120
0121 if rev >= 24
0122 nld = size(data.load.num, 1);
0123 loadbus = e2i(data.load.num(:,1));
0124
0125
0126
0127
0128
0129
0130 Pd = data.load.num(:,6) + data.load.num(:,8) .* bus(loadbus, VM) ...
0131 + data.load.num(:,10) .* bus(loadbus, VM).^2;
0132 Qd = data.load.num(:,7) + data.load.num(:,9) .* bus(loadbus, VM) ...
0133 - data.load.num(:,11) .* bus(loadbus, VM).^2;
0134 Cld = sparse(1:nld, loadbus, data.load.num(:,3), nld, nb);
0135 bus(:, [PD QD]) = Cld' * [Pd Qd];
0136 end
0137
0138
0139 if isfield(data, 'shunt')
0140 nsh = size(data.shunt.num, 1);
0141 shuntbus = e2i(data.shunt.num(:,1));
0142 Csh = sparse(1:nsh, shuntbus, data.shunt.num(:,3), nsh, nb);
0143 bus(:, [GS BS]) = Csh' * data.shunt.num(:, 4:5);
0144 end
0145
0146
0147 nswsh = size(data.swshunt.num, 1);
0148 swshuntbus = e2i(data.swshunt.num(:,1));
0149 Cswsh = sparse(1:nswsh, swshuntbus, 1, nswsh, nb);
0150 if rev <= 27
0151 bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 6);
0152 elseif rev <= 29
0153 bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 7);
0154 elseif rev < 32
0155 bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 8);
0156 else
0157 bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 10);
0158 end
0159
0160
0161 nbr = size(data.branch.num, 1);
0162 branch = zeros(nbr, ANGMAX);
0163 branch(:, ANGMIN) = -360;
0164 branch(:, ANGMAX) = 360;
0165 branch(:, [F_BUS BR_R BR_X BR_B RATE_A RATE_B RATE_C]) = ...
0166 data.branch.num(:, [1 4 5 6 7 8 9]);
0167 branch(:, T_BUS) = abs(data.branch.num(:, 2));
0168 if rev <= 27
0169 branch(:, BR_STATUS) = data.branch.num(:, 16);
0170 branch(~isnan(data.branch.num(:, 10)), TAP) = ...
0171 data.branch.num(~isnan(data.branch.num(:, 10)), 10);
0172 branch(~isnan(data.branch.num(:, 11)), SHIFT) = ...
0173 data.branch.num(~isnan(data.branch.num(:, 11)), 11);
0174 else
0175 branch(:, BR_STATUS) = data.branch.num(:, 14);
0176 end
0177
0178 ibr = (1:nbr)';
0179 fbus = e2i(branch(:, F_BUS));
0180 tbus = e2i(branch(:, T_BUS));
0181 nzf = find(fbus);
0182 nzt = find(tbus);
0183 if length(nzf) < nbr
0184 warns{end+1} = sprintf('%d branches have bad ''from'' bus numbers', nbr-length(nzf));
0185 if verbose
0186 fprintf('WARNING: %d branches have bad ''from'' bus numbers\n', nbr-length(nzf));
0187 end
0188 end
0189 if length(nzt) < nbr
0190 warns{end+1} = sprintf('%d branches have bad ''to'' bus numbers', nbr-length(nzt));
0191 if verbose
0192 fprintf('WARNING: %d branches have bad ''to'' bus numbers\n', nbr-length(nzt));
0193 end
0194 end
0195 Cf = sparse(ibr(nzf), fbus(nzf), branch(nzf, BR_STATUS), nbr, nb);
0196 Ct = sparse(ibr(nzt), tbus(nzt), branch(nzt, BR_STATUS), nbr, nb);
0197 if rev <= 27
0198 bus(:, [GS BS]) = bus(:, [GS BS]) + ...
0199 Cf' * data.branch.num(:, 12:13)*baseMVA + ...
0200 Ct' * data.branch.num(:, 14:15)*baseMVA;
0201 else
0202 bus(:, [GS BS]) = bus(:, [GS BS]) + ...
0203 Cf' * data.branch.num(:, 10:11)*baseMVA + ...
0204 Ct' * data.branch.num(:, 12:13)*baseMVA;
0205 end
0206
0207
0208 ng = size(data.gen.num, 1);
0209 genbus = e2i(data.gen.num(:,1));
0210 gen = zeros(ng, APF);
0211 gen = zeros(ng, MU_QMIN);
0212 gen(:, [GEN_BUS PG QG QMAX QMIN VG MBASE GEN_STATUS PMAX PMIN]) = ...
0213 data.gen.num(:, [1 3 4 5 6 7 9 15 17 18]);
0214
0215
0216 if rev > 27
0217 [transformer, bus, warns, bus_name] = psse_convert_xfmr(warns, data.trans2.num, data.trans3.num, verbose, baseMVA, bus, bus_name);
0218 branch = [branch; transformer];
0219 end
0220
0221
0222 dcline = psse_convert_hvdc(data.twodc.num, bus);
0223
0224
0225 mpc = struct( ...
0226 'baseMVA', baseMVA, ...
0227 'bus', bus, ...
0228 'bus_name', {bus_name}, ...
0229 'branch', branch, ...
0230 'gen', gen ...
0231 );
0232 if ~isempty(dcline)
0233 mpc.dcline = dcline;
0234 mpc = toggle_dcline(mpc, 'on');
0235 end