Home > matpower7.1 > lib > psse_convert.m

psse_convert

PURPOSE ^

PSSE_CONVERT Converts data read from PSS/E RAW file to MATPOWER case.

SYNOPSIS ^

function [mpc, warns] = psse_convert(warns, data, verbose)

DESCRIPTION ^

PSSE_CONVERT  Converts data read from PSS/E RAW file to MATPOWER case.
   [MPC, WARNINGS] = PSSE_CONVERT(WARNINGS, DATA)
   [MPC, WARNINGS] = PSSE_CONVERT(WARNINGS, DATA, VERBOSE)

   Converts data read from a version RAW data file into a
   MATPOWER case struct.

   Input:
       WARNINGS :  cell array of strings containing accumulated
                   warning messages
       DATA : struct read by PSSE_READ (see PSSE_READ for details).
       VERBOSE :   1 to display progress info, 0 (default) otherwise

   Output:
       MPC : a MATPOWER case struct created from the PSS/E data
       WARNINGS :  cell array of strings containing updated accumulated
                   warning messages

   See also PSSE_READ.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [mpc, warns] = psse_convert(warns, data, verbose)
0002 %PSSE_CONVERT  Converts data read from PSS/E RAW file to MATPOWER case.
0003 %   [MPC, WARNINGS] = PSSE_CONVERT(WARNINGS, DATA)
0004 %   [MPC, WARNINGS] = PSSE_CONVERT(WARNINGS, DATA, VERBOSE)
0005 %
0006 %   Converts data read from a version RAW data file into a
0007 %   MATPOWER case struct.
0008 %
0009 %   Input:
0010 %       WARNINGS :  cell array of strings containing accumulated
0011 %                   warning messages
0012 %       DATA : struct read by PSSE_READ (see PSSE_READ for details).
0013 %       VERBOSE :   1 to display progress info, 0 (default) otherwise
0014 %
0015 %   Output:
0016 %       MPC : a MATPOWER case struct created from the PSS/E data
0017 %       WARNINGS :  cell array of strings containing updated accumulated
0018 %                   warning messages
0019 %
0020 %   See also PSSE_READ.
0021 
0022 %   MATPOWER
0023 %   Copyright (c) 2014-2016, Power Systems Engineering Research Center (PSERC)
0024 %   by Yujia Zhu, PSERC ASU
0025 %   and Ray Zimmerman, PSERC Cornell
0026 %   Based on mpraw2mp.m, written by: Yujia Zhu, Jan 2014, yzhu54@asu.edu.
0027 %
0028 %   This file is part of MATPOWER.
0029 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0030 %   See https://matpower.org for more info.
0031 
0032 %% define named indices into bus, gen, branch matrices
0033 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0034     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0035 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0036     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0037     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0038 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0039     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0040     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0041 
0042 %% options
0043 sort_buses = 1;
0044 
0045 %% defaults
0046 if nargin < 3
0047     verbose = 0;
0048 end
0049 haveVlims = 0;
0050 Vmin = 0.9;
0051 Vmax = 1.1;
0052 
0053 %%-----  case identification data  -----
0054 baseMVA = data.id.SBASE;
0055 rev = data.id.REV;
0056 
0057 %%-----  bus data  -----
0058 numbus = data.bus.num;
0059 [nb, ncols] = size(numbus); %% number of buses, number of cols
0060 bus = zeros(nb, VMIN);      %% initialize bus matrix
0061 if rev < 24
0062     bus_name_col = 10;
0063 else
0064     bus_name_col = 2;
0065 end
0066 if sort_buses
0067     [numbus, i] = sortrows(numbus, 1);
0068     bus_name = data.bus.txt(i, bus_name_col);
0069 else
0070     bus_name = data.bus.txt(:, bus_name_col);
0071 end
0072 if rev < 24     %% includes loads
0073     bus(:, [BUS_I BUS_TYPE PD QD GS BS BUS_AREA VM VA BASE_KV ZONE]) = ...
0074         numbus(:, [1:9 11:12]);
0075 elseif rev < 31     %% includes GL, BL
0076     bus(:, [BUS_I BASE_KV BUS_TYPE GS BS BUS_AREA ZONE VM VA]) = ...
0077         numbus(:, [1 3 4 5 6 7 8 9 10]);
0078 else                %% fixed shunts and loads are in their own tables
0079     bus(:, [BUS_I BASE_KV BUS_TYPE BUS_AREA ZONE VM VA]) = ...
0080         numbus(:, [1 3 4 5 6 8 9]);
0081     if ncols >= 11 && all(all(~isnan(numbus(:, [10 11]))))
0082         haveVlims = 1;
0083         bus(:, [VMAX VMIN]) = numbus(:, [10 11]);
0084     end
0085 end
0086 if ~haveVlims  %% add default voltage magnitude limits if not provided
0087     warns{end+1} = sprintf('Using default voltage magnitude limits: VMIN = %g p.u., VMAX = %g p.u.', Vmin, Vmax);
0088     if verbose
0089         fprintf('WARNING: No bus voltage magnitude limits provided.\n         Using defaults: VMIN = %g p.u., VMAX = %g p.u.\n', Vmin, Vmax);
0090     end
0091     bus(:, VMIN) = Vmin;
0092     bus(:, VMAX) = Vmax;
0093 end
0094 
0095 %% create map of external bus numbers to bus indices
0096 i2e = bus(:, BUS_I);
0097 e2i = sparse(i2e, ones(nb, 1), 1:nb, max(i2e), 1);
0098 
0099 %%-----  load data  -----
0100 if rev >= 24
0101     nld = size(data.load.num, 1);
0102     loadbus = e2i(data.load.num(:,1));
0103     %% PSS/E loads are divided into:
0104     %%  1. constant MVA, (I=1)
0105     %%  2. constant current (I=I)
0106     %%  3. constant reactance/resistance (I = I^2)
0107     %% NOTE: reactive power component of constant admittance load is negative
0108     %%       quantity for inductive load and positive for capacitive load
0109     Pd = data.load.num(:,6) + data.load.num(:,8) .* bus(loadbus, VM) ...
0110             + data.load.num(:,10) .* bus(loadbus, VM).^2;
0111     Qd = data.load.num(:,7) + data.load.num(:,9) .* bus(loadbus, VM) ...
0112             - data.load.num(:,11) .* bus(loadbus, VM).^2;
0113     Cld = sparse(1:nld, loadbus, data.load.num(:,3), nld, nb);    %% only in-service-loads
0114     bus(:, [PD QD]) = Cld' * [Pd Qd];
0115 end
0116 
0117 %%-----  fixed shunt data  -----
0118 if isfield(data, 'shunt')   %% rev > 30
0119     nsh = size(data.shunt.num, 1);
0120     shuntbus = e2i(data.shunt.num(:,1));
0121     Csh = sparse(1:nsh, shuntbus, data.shunt.num(:,3), nsh, nb);  %% only in-service shunts
0122     bus(:, [GS BS]) = Csh' * data.shunt.num(:, 4:5);
0123 end
0124 
0125 %%-----  switched shunt data  -----
0126 nswsh = size(data.swshunt.num, 1);
0127 swshuntbus = e2i(data.swshunt.num(:,1));
0128 Cswsh = sparse(1:nswsh, swshuntbus, 1, nswsh, nb);
0129 if rev <= 27
0130     bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 6);
0131 elseif rev <= 29
0132     bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 7);
0133 elseif rev < 32
0134     bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 8);
0135 else
0136     bus(:, BS) = bus(:, BS) + Cswsh' * data.swshunt.num(:, 10);
0137 end
0138 
0139 %%-----  branch data  -----
0140 nbr = size(data.branch.num, 1);
0141 branch = zeros(nbr, ANGMAX);
0142 branch(:, ANGMIN) = -360;
0143 branch(:, ANGMAX) = 360;
0144 branch(:, [F_BUS BR_R BR_X BR_B RATE_A RATE_B RATE_C]) = ...
0145     data.branch.num(:, [1 4 5 6 7 8 9]);
0146 branch(:, T_BUS) = abs(data.branch.num(:, 2));  %% can be negative to indicate metered end
0147 if rev <= 27        %% includes transformer ratio, angle
0148     branch(:, BR_STATUS) = data.branch.num(:, 16);
0149     branch(~isnan(data.branch.num(:, 10)), TAP) = ...
0150         data.branch.num(~isnan(data.branch.num(:, 10)), 10);
0151     branch(~isnan(data.branch.num(:, 11)), SHIFT) = ...
0152         data.branch.num(~isnan(data.branch.num(:, 11)), 11);
0153 else
0154     branch(:, BR_STATUS)    = data.branch.num(:, 14);
0155 end
0156 %% integrate branch shunts (explicit shunts, not line-charging)
0157 ibr = (1:nbr)';
0158 fbus = e2i(branch(:, F_BUS));
0159 tbus = e2i(branch(:, T_BUS));
0160 nzf = find(fbus);               %% ignore branches with bad bus numbers
0161 nzt = find(tbus);
0162 if length(nzf) < nbr
0163     warns{end+1} = sprintf('%d branches have bad ''from'' bus numbers', nbr-length(nzf));
0164     if verbose
0165         fprintf('WARNING: %d branches have bad ''from'' bus numbers\n', nbr-length(nzf));
0166     end
0167 end
0168 if length(nzt) < nbr
0169     warns{end+1} = sprintf('%d branches have bad ''to'' bus numbers', nbr-length(nzt));
0170     if verbose
0171         fprintf('WARNING: %d branches have bad ''to'' bus numbers\n', nbr-length(nzt));
0172     end
0173 end
0174 Cf = sparse(ibr(nzf), fbus(nzf), branch(nzf, BR_STATUS), nbr, nb);  %% only in-service branches
0175 Ct = sparse(ibr(nzt), tbus(nzt), branch(nzt, BR_STATUS), nbr, nb);  %% only in-service branches
0176 if rev <= 27
0177     bus(:, [GS BS]) = bus(:, [GS BS]) + ...
0178         Cf' * data.branch.num(:, 12:13)*baseMVA + ...
0179         Ct' * data.branch.num(:, 14:15)*baseMVA;
0180 else
0181     bus(:, [GS BS]) = bus(:, [GS BS]) + ...
0182         Cf' * data.branch.num(:, 10:11)*baseMVA + ...
0183         Ct' * data.branch.num(:, 12:13)*baseMVA;
0184 end
0185 
0186 %%-----  generator data  -----
0187 ng = size(data.gen.num, 1);
0188 genbus = e2i(data.gen.num(:,1));
0189 gen = zeros(ng, APF);
0190 gen(:, [GEN_BUS PG QG QMAX QMIN VG MBASE GEN_STATUS PMAX PMIN]) = ...
0191     data.gen.num(:, [1 3 4 5 6 7 9 15 17 18]);
0192 
0193 %%-----  transformer data  -----
0194 if rev > 27
0195     [transformer, bus, warns, bus_name] = psse_convert_xfmr(warns, data.trans2.num, data.trans3.num, verbose, baseMVA, bus, bus_name);
0196     branch = [branch; transformer];
0197 end
0198 
0199 %%-----  two-terminal DC transmission line data  -----
0200 dcline = psse_convert_hvdc(data.twodc.num, bus);
0201 
0202 %% assemble MPC
0203 mpc = struct( ...
0204     'baseMVA',  baseMVA, ...
0205     'bus', bus, ...
0206     'bus_name', {bus_name}, ...
0207     'branch', branch, ...
0208     'gen', gen ...
0209 );
0210 if ~isempty(dcline)
0211     mpc.dcline = dcline;
0212     mpc = toggle_dcline(mpc, 'on');
0213 end

Generated on Fri 09-Oct-2020 11:21:31 by m2html © 2005