Home > matpower5.1 > cdf2mpc.m

cdf2mpc

PURPOSE ^

CDF2MPC Converts an IEEE CDF data file into a MATPOWER case struct.

SYNOPSIS ^

function [mpc, warnings] = cdf2mpc(cdf_file_name, mpc_name, verbose)

DESCRIPTION ^

CDF2MPC  Converts an IEEE CDF data file into a MATPOWER case struct.
   MPC = CDF2MPC(CDF_FILE_NAME)
   MPC = CDF2MPC(CDF_FILE_NAME, VERBOSE)
   MPC = CDF2MPC(CDF_FILE_NAME, MPC_NAME)
   MPC = CDF2MPC(CDF_FILE_NAME, MPC_NAME, VERBOSE)
   [MPC, WARNINGS] = CDF2MPC(CDF_FILE_NAME, ...)

   Converts an IEEE Common Data Format (CDF) data file into a MATPOWER case
   struct.

   Input:
       CDF_FILE_NAME :  name of the IEEE CDF file to be converted
       MPC_NAME      :  (optional) file name to use to save the resulting
                         MATPOWER case
       VERBOSE       :  1 (default) to display progress info, 0 otherwise

   Output(s):
       MPC      : resulting MATPOWER case struct
       WARNINGS : (optional) cell array of strings containing warning
                  messages (included by default in comments of MPC_NAME).

   The IEEE CDF does not include some data need to run an optimal power
   flow. This script creates default values for some of this data as
   follows:

       Bus data:
           Vmin = 0.94 p.u.
           Vmax = 1.06 p.u.
       Gen data:
           Pmin = 0 MW
           Pmax = Pg + baseMVA
       Gen cost data:
           Quadratic costs with:
               c2 = 10 / Pg, c1 = 20, c0 = 0, if Pg is non-zero, and
               c2 = 0.01,    c1 = 40, c0 = 0, if Pg is zero
           This should yield an OPF solution "close" to the
           existing solution (assuming it is a solved case)
           with lambdas near $40/MWh. See 'help caseformat'
           for details on the cost curve format.

   CDF2MPC may modify some of the data which are "infeasible" for
   running optimal power flow. If so, warning information will be
   printed out on screen.

   Note: Since our code can not handle transformers with variable tap,
   you may not expect to get exactly the same power flow solution
   using converted data. This is the case when we converted ieee300.cdf.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [mpc, warnings] = cdf2mpc(cdf_file_name, mpc_name, verbose)
0002 %CDF2MPC  Converts an IEEE CDF data file into a MATPOWER case struct.
0003 %   MPC = CDF2MPC(CDF_FILE_NAME)
0004 %   MPC = CDF2MPC(CDF_FILE_NAME, VERBOSE)
0005 %   MPC = CDF2MPC(CDF_FILE_NAME, MPC_NAME)
0006 %   MPC = CDF2MPC(CDF_FILE_NAME, MPC_NAME, VERBOSE)
0007 %   [MPC, WARNINGS] = CDF2MPC(CDF_FILE_NAME, ...)
0008 %
0009 %   Converts an IEEE Common Data Format (CDF) data file into a MATPOWER case
0010 %   struct.
0011 %
0012 %   Input:
0013 %       CDF_FILE_NAME :  name of the IEEE CDF file to be converted
0014 %       MPC_NAME      :  (optional) file name to use to save the resulting
0015 %                         MATPOWER case
0016 %       VERBOSE       :  1 (default) to display progress info, 0 otherwise
0017 %
0018 %   Output(s):
0019 %       MPC      : resulting MATPOWER case struct
0020 %       WARNINGS : (optional) cell array of strings containing warning
0021 %                  messages (included by default in comments of MPC_NAME).
0022 %
0023 %   The IEEE CDF does not include some data need to run an optimal power
0024 %   flow. This script creates default values for some of this data as
0025 %   follows:
0026 %
0027 %       Bus data:
0028 %           Vmin = 0.94 p.u.
0029 %           Vmax = 1.06 p.u.
0030 %       Gen data:
0031 %           Pmin = 0 MW
0032 %           Pmax = Pg + baseMVA
0033 %       Gen cost data:
0034 %           Quadratic costs with:
0035 %               c2 = 10 / Pg, c1 = 20, c0 = 0, if Pg is non-zero, and
0036 %               c2 = 0.01,    c1 = 40, c0 = 0, if Pg is zero
0037 %           This should yield an OPF solution "close" to the
0038 %           existing solution (assuming it is a solved case)
0039 %           with lambdas near $40/MWh. See 'help caseformat'
0040 %           for details on the cost curve format.
0041 %
0042 %   CDF2MPC may modify some of the data which are "infeasible" for
0043 %   running optimal power flow. If so, warning information will be
0044 %   printed out on screen.
0045 %
0046 %   Note: Since our code can not handle transformers with variable tap,
0047 %   you may not expect to get exactly the same power flow solution
0048 %   using converted data. This is the case when we converted ieee300.cdf.
0049 
0050 %   MATPOWER
0051 %   Copyright (c) 1996-2015 by Power System Engineering Research Center (PSERC)
0052 %   by Deqiang (David) Gan, PSERC Cornell & Zhejiang University
0053 %   and Ray Zimmerman, PSERC Cornell
0054 %
0055 %   $Id: cdf2mpc.m 2644 2015-03-11 19:34:22Z ray $
0056 %
0057 %   This file is part of MATPOWER.
0058 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0059 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0060 
0061 %% define named indices into bus, gen, branch matrices
0062 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0063     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0064 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0065     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0066     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0067 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0068     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0069     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0070 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0071 
0072 %% handle input args
0073 if nargin < 2
0074     verbose = 1;
0075     mpc_name = '';
0076 elseif ischar(mpc_name)     %% save the file
0077     if nargin < 3
0078         verbose = 1;
0079     end
0080 else                        %% don't save the file
0081     verbose = mpc_name;
0082     mpc_name = '';
0083 end
0084 
0085 %%-----  read data from CDF file into mpc fields
0086 %% verify valid input filename
0087 [cdf_path cdf_name cdf_ext] = fileparts(cdf_file_name);
0088 if isempty(cdf_ext)
0089     cdf_ext = '.cdf';
0090     cdf_file_name = strcat(cdf_name , cdf_ext);
0091 end
0092 
0093 %% open input file
0094 [fid, msg] = fopen(cdf_file_name, 'r');
0095 if fid < 0
0096     disp(msg);
0097     error('cdf2mpc: Can not read the input file:  %s', cdf_file_name )
0098 end
0099 if verbose
0100     fprintf('Converting file ''%s''\n', cdf_file_name);
0101     fprintf('  WARNINGS:\n');
0102 end
0103 
0104 %% initialize list of warnings
0105 warnings = {};
0106 
0107 % get baseMVA
0108 title_cdf = fgetl(fid);
0109 if isnumeric(str2num(title_cdf(32:37))) && not(isempty(str2num(title_cdf(32:37))))
0110     baseMVA = str2num(title_cdf(32:37));
0111     if length(findstr(title_cdf(2:9), '/')) == 2    %% date in the file
0112         warnings{end+1} = sprintf('check the title format in the first line of the cdf file.');
0113     end
0114 else
0115     error('cdf2mpc: Error getting the Base MVA, check the title format in the first line of the file.')
0116 end
0117     
0118 % find string 'BUS DATA FOLLOWS'
0119 while 1
0120     line = fgetl(fid);
0121     if line(1:16) == 'BUS DATA FOLLOWS', break, end
0122 end
0123 
0124 % ----- get bus data, feed them into matrix bus, gen, gencost
0125 ibus = 0;
0126 igen = 0;
0127 iarea = 0;
0128 
0129 while 1
0130     line = fgetl(fid);
0131     if line(1:4) == '-999', break, end
0132 
0133     % feed bus data
0134     ibus = ibus + 1;
0135     bus(ibus, BUS_I) = str2num(line(1:4));          % bus number
0136     bus_name{ibus} = strtrim(line(6:17));           % bus names
0137     bus(ibus, BUS_TYPE) = str2num(line(25:26));
0138     if bus(ibus, BUS_TYPE) == 0                     % bus type
0139         bus(ibus, BUS_TYPE) = 1;
0140     end
0141     if (bus(ibus, BUS_TYPE) < 2)                    % Pd
0142         bus(ibus, PD) = str2num(line(41:49)) - str2num(line(60:67));
0143     elseif (bus(ibus, BUS_TYPE) >= 2)
0144         bus(ibus, PD) = str2num(line(41:49));
0145     end
0146     bus(ibus, QD) = str2num(line(50:59));           % Qd
0147     bus(ibus, GS) = baseMVA*str2num(line(107:114)); % Gs
0148     bus(ibus, BS) = baseMVA*str2num(line(115:122)); % Bs
0149     bus(ibus, BUS_AREA) = str2num(line(19:20));     % area
0150     bus(ibus, VM) = str2num(line(28:33));           % Vm
0151     bus(ibus, VA) = str2num(line(34:40));           % Va
0152     bus(ibus, BASE_KV) = str2num(line(77:83));      % baseKV
0153     bus(ibus, ZONE) = str2num(line(21:23));         % zone
0154     bus(ibus, VMAX) = 1.06;                         % default voltage upper limit
0155     bus(ibus, VMIN) = 0.94;                         % default voltage lower limit
0156 
0157     % feed gen and gencost
0158     Pg = str2num(line(60:67));
0159     Qg = str2num(line(68:75));
0160     Qmax = str2num(line(91:98));
0161     Qmin = str2num(line(99:106));
0162     if bus(ibus, BUS_TYPE) >= 2
0163         igen = igen + 1;
0164         if bus(ibus, BUS_TYPE) == 3, refgen = igen; end
0165         gen(igen, GEN_BUS) = bus(ibus, BUS_I);      % bus number
0166         gen(igen, PG) = Pg;                         % Pg
0167         if gen(igen, PG) < 0                        % negative Pg is transformed as load
0168             bus(ibus, PD) = bus(ibus, PD) - gen(igen, PG);
0169             warnings{end+1} = sprintf('negative Pg at bus %g treated as Pd', bus(ibus, BUS_I));
0170             if verbose
0171                 fprintf('    %s\n', warnings{end});
0172             end
0173             gen(igen, PG) = 0;
0174         end
0175         gen(igen, QG)   = Qg;                       % Qg
0176         gen(igen, QMAX) = Qmax;                     % Qmax
0177         gen(igen, QMIN) = Qmin;                     % Qmin
0178         if Qmax - Qmin < 0.01                       % Qmax is modified
0179             gen(igen, QMAX) = Qmin + 0.1 * baseMVA;
0180             warnings{end+1} = sprintf('Qmax = Qmin at generator at bus %4i (Qmax set to Qmin + %g)', bus(ibus, BUS_I), baseMVA/10);
0181             if verbose
0182                 fprintf('    %s\n', warnings{end});
0183             end
0184         end
0185         gen(igen, VG)    = str2num(line(85:90));    % specified voltage
0186         gen(igen, MBASE) = baseMVA;                 % baseMVA
0187         gen(igen, GEN_STATUS) = 1;                  % default status is 'on'
0188         gen(igen, PMAX)  = gen(igen, 2) + baseMVA;  % Pmax
0189         gen(igen, PMIN)  = 0;                       % Pmin = 0 by default
0190 
0191         gencost(igen, MODEL)    = POLYNOMIAL;       % by default, sets the model as polynomial
0192         gencost(igen, STARTUP)  = 0;                % start up cost is zero by default
0193         gencost(igen, SHUTDOWN) = 0;                % shut down cost is zero by default
0194         gencost(igen, NCOST)    = 3;                % number of coefficients in polynomial cost
0195 %       gencost(igen, COST)     = 0.01;             % default c2
0196 %       gencost(igen, COST+1)   = 0.3;              % default c1
0197 %       gencost(igen, COST+2)   = 0.2;              % default c0
0198     end
0199 end
0200 
0201 totload = sum(bus(:, PD));
0202 totgen = sum(gen(:, PG));
0203 if totgen < 1.04 * totload
0204     gen(refgen, PMAX) = gen(refgen, PG) + 1.1 * totload - totgen;   % Pg at slack bus is modified
0205     warnings{end+1} = sprintf('Insufficient generation, setting Pmax at slack bus (bus %d) to %g', gen(refgen, [GEN_BUS, PMAX]));
0206     if verbose
0207         fprintf('    %s\n', warnings{end});
0208     end
0209 end
0210 
0211 % ----- set up the cost coefficients of generators
0212 ng = size(gen, 1);
0213 % gencost(:, COST)    = zeros(ng, 1);
0214 % gencost(:, COST+1)  = 100*ones(ng, 1) ./ (gen(:, PG) + 10*ones(ng, 1));
0215 % gencost(:, COST+2)  = 100*ones(ng, 1) ./ (gen(:, PG) + 10*ones(ng, 1));
0216 zg  = find(gen(:, PG) == 0);                %% for Pg = 0
0217 gencost(zg, COST)  = 0.01 * ones(size(zg));
0218 gencost(zg, COST+1) = 40 * ones(size(zg));
0219 nzg = find(gen(:, PG) ~= 0);                %% Pg non-zero
0220 gencost(nzg, COST) = 10 * ones(size(nzg)) ./ gen(nzg, PG);
0221 gencost(nzg, COST+1) = 20 * ones(size(nzg));
0222 gencost(:, COST+2) = zeros(ng, 1);
0223 
0224 % find string 'BRANCH DATA FOLLOWS'
0225 while 1
0226     line = fgetl(fid);
0227     if line(1:19) == 'BRANCH DATA FOLLOWS', break, end
0228 end
0229 
0230 % ----- get branch data, feed them into matrix branch
0231 k = 0;
0232 while 1
0233     line = fgetl(fid);
0234     if line(1:4) == '-999', break, end
0235 
0236     k = k + 1;
0237     branch(k, F_BUS)  = str2num(line(1:4));     % fbus (also the tap bus)
0238     branch(k, T_BUS)  = str2num(line(6:9));     % tbus
0239     branch(k, BR_R)   = str2num(line(20:29));   % R
0240     branch(k, BR_X)   = str2num(line(30:40));   % X
0241     branch(k, BR_B)   = str2num(line(41:50));   % B
0242     branch(k, RATE_A) = str2num(line(51:55));   % RATE A
0243     if branch(k, RATE_A) < 0.000001
0244         branch(k, RATE_A) = 0;                  % RATE A is modified
0245         warnings{end+1} = sprintf('MVA limit of branch %d - %d not given, set to %g', branch(k, [F_BUS, T_BUS, RATE_A]));
0246         if verbose
0247             fprintf('    %s\n', warnings{end});
0248         end
0249     end
0250     branch(k, RATE_B) = str2num(line(57:61));   % RATE B
0251     branch(k, RATE_C) = str2num(line(63:67));   % RATE C
0252     branch(k, TAP)    = str2num(line(77:82));   % transformer turns ratio
0253     branch(k, SHIFT)  = 0;                      % phase shifter can not be modelled
0254     branch(k, BR_STATUS) = 1;                   % by default, branch is on
0255 end
0256 if verbose
0257     fprintf('Done.\n');
0258 end
0259 fclose(fid);
0260 
0261 % put in struct
0262 mpc.baseMVA = baseMVA;
0263 mpc.bus     = bus;
0264 mpc.branch  = branch;
0265 mpc.gen     = gen;
0266 mpc.gencost = gencost;
0267 mpc.bus_name = bus_name;
0268 mpc = loadcase(mpc);    %% convert to internal (e.g. v. '2') case format
0269 
0270 %% (optionally) save MATPOWER case file
0271 if ~isempty(mpc_name)
0272     comments = {''};
0273     if ~isempty(title_cdf)
0274         comments{end+1} = sprintf('   %s', title_cdf);
0275     end
0276     comments{end+1} = '';
0277     comments{end+1} = sprintf('   Converted by MATPOWER %s using CDF2MPC on %s', mpver, date);
0278     comments{end+1} = sprintf('   from ''%s''.', cdf_file_name);
0279 
0280     %% warnings
0281     comments{end+1} = '';
0282     comments{end+1} = '   WARNINGS:';
0283     for k = 1:length(warnings)
0284         comments{end+1} = sprintf('       %s', warnings{k});
0285     end
0286     comments{end+1} = '';
0287     comments{end+1} = sprintf('   See CASEFORMAT for details on the MATPOWER case file format.');
0288 
0289     if verbose
0290         spacers = repmat('.', 1, 45-length(mpc_name));
0291         fprintf('Saving to MATPOWER case ''%s'' %s', mpc_name, spacers);
0292     end
0293     savecase(mpc_name, comments, mpc);
0294     if verbose
0295         fprintf(' done.\n');
0296     end
0297 end

Generated on Fri 20-Mar-2015 18:23:34 by m2html © 2005