Home > matpower5.0 > 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 %   $Id: cdf2mpc.m 2443 2014-12-05 16:12:31Z ray $
0052 %   by Deqiang (David) Gan, PSERC Cornell & Zhejiang University
0053 %   and Ray Zimmerman, PSERC Cornell
0054 %   Copyright (c) 1996-2014 by Power System Engineering Research Center (PSERC)
0055 %
0056 %   This file is part of MATPOWER.
0057 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0058 %
0059 %   MATPOWER is free software: you can redistribute it and/or modify
0060 %   it under the terms of the GNU General Public License as published
0061 %   by the Free Software Foundation, either version 3 of the License,
0062 %   or (at your option) any later version.
0063 %
0064 %   MATPOWER is distributed in the hope that it will be useful,
0065 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0066 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0067 %   GNU General Public License for more details.
0068 %
0069 %   You should have received a copy of the GNU General Public License
0070 %   along with MATPOWER. If not, see <http://www.gnu.org/licenses/>.
0071 %
0072 %   Additional permission under GNU GPL version 3 section 7
0073 %
0074 %   If you modify MATPOWER, or any covered work, to interface with
0075 %   other modules (such as MATLAB code and MEX-files) available in a
0076 %   MATLAB(R) or comparable environment containing parts covered
0077 %   under other licensing terms, the licensors of MATPOWER grant
0078 %   you additional permission to convey the resulting work.
0079 
0080 %% define named indices into bus, gen, branch matrices
0081 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0082     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0083 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0084     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0085     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0086 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0087     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0088     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0089 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0090 
0091 %% handle input args
0092 if nargin < 2
0093     verbose = 1;
0094     mpc_name = '';
0095 elseif ischar(mpc_name)     %% save the file
0096     if nargin < 3
0097         verbose = 1;
0098     end
0099 else                        %% don't save the file
0100     verbose = mpc_name;
0101     mpc_name = '';
0102 end
0103 
0104 %%-----  read data from CDF file into mpc fields
0105 %% verify valid input filename
0106 [cdf_path cdf_name cdf_ext] = fileparts(cdf_file_name);
0107 if isempty(cdf_ext)
0108     cdf_ext = '.cdf';
0109     cdf_file_name = strcat(cdf_name , cdf_ext);
0110 end
0111 
0112 %% open input file
0113 [fid, msg] = fopen(cdf_file_name, 'r');
0114 if fid < 0
0115     disp(msg);
0116     error('cdf2mpc: Can not read the input file:  %s', cdf_file_name )
0117 end
0118 if verbose
0119     fprintf('Converting file ''%s''\n', cdf_file_name);
0120     fprintf('  WARNINGS:\n');
0121 end
0122 
0123 %% initialize list of warnings
0124 warnings = {};
0125 
0126 % get baseMVA
0127 title_cdf = fgetl(fid);
0128 if isnumeric(str2num(title_cdf(32:37))) && not(isempty(str2num(title_cdf(32:37))))
0129     baseMVA = str2num(title_cdf(32:37));
0130     if length(findstr(title_cdf(2:9), '/')) == 2    %% date in the file
0131         warnings{end+1} = sprintf('check the title format in the first line of the cdf file.');
0132     end
0133 else
0134     error('cdf2mpc: Error getting the Base MVA, check the title format in the first line of the file.')
0135 end
0136     
0137 % find string 'BUS DATA FOLLOWS'
0138 while 1
0139     line = fgetl(fid);
0140     if line(1:16) == 'BUS DATA FOLLOWS', break, end
0141 end
0142 
0143 % ----- get bus data, feed them into matrix bus, gen, gencost
0144 ibus = 0;
0145 igen = 0;
0146 iarea = 0;
0147 
0148 while 1
0149     line = fgetl(fid);
0150     if line(1:4) == '-999', break, end
0151 
0152     % feed bus data
0153     ibus = ibus + 1;
0154     bus(ibus, BUS_I) = str2num(line(1:4));          % bus number
0155     bus_name{ibus} = strtrim(line(6:17));           % bus names
0156     bus(ibus, BUS_TYPE) = str2num(line(25:26));
0157     if bus(ibus, BUS_TYPE) == 0                     % bus type
0158         bus(ibus, BUS_TYPE) = 1;
0159     end
0160     if (bus(ibus, BUS_TYPE) < 2)                    % Pd
0161         bus(ibus, PD) = str2num(line(41:49)) - str2num(line(60:67));
0162     elseif (bus(ibus, BUS_TYPE) >= 2)
0163         bus(ibus, PD) = str2num(line(41:49));
0164     end
0165     bus(ibus, QD) = str2num(line(50:59));           % Qd
0166     bus(ibus, GS) = baseMVA*str2num(line(107:114)); % Gs
0167     bus(ibus, BS) = baseMVA*str2num(line(115:122)); % Bs
0168     bus(ibus, BUS_AREA) = str2num(line(19:20));     % area
0169     bus(ibus, VM) = str2num(line(28:33));           % Vm
0170     bus(ibus, VA) = str2num(line(34:40));           % Va
0171     bus(ibus, BASE_KV) = str2num(line(77:83));      % baseKV
0172     bus(ibus, ZONE) = str2num(line(21:23));         % zone
0173     bus(ibus, VMAX) = 1.06;                         % default voltage upper limit
0174     bus(ibus, VMIN) = 0.94;                         % default voltage lower limit
0175 
0176     % feed gen and gencost
0177     Pg = str2num(line(60:67));
0178     Qg = str2num(line(68:75));
0179     Qmax = str2num(line(91:98));
0180     Qmin = str2num(line(99:106));
0181     if bus(ibus, BUS_TYPE) >= 2
0182         igen = igen + 1;
0183         if bus(ibus, BUS_TYPE) == 3, refgen = igen; end
0184         gen(igen, GEN_BUS) = bus(ibus, BUS_I);      % bus number
0185         gen(igen, PG) = Pg;                         % Pg
0186         if gen(igen, PG) < 0                        % negative Pg is transformed as load
0187             bus(ibus, PD) = bus(ibus, PD) - gen(igen, PG);
0188             warnings{end+1} = sprintf('negative Pg at bus %g treated as Pd', bus(ibus, BUS_I));
0189             if verbose
0190                 fprintf('    %s\n', warnings{end});
0191             end
0192             gen(igen, PG) = 0;
0193         end
0194         gen(igen, QG)   = Qg;                       % Qg
0195         gen(igen, QMAX) = Qmax;                     % Qmax
0196         gen(igen, QMIN) = Qmin;                     % Qmin
0197         if Qmax - Qmin < 0.01                       % Qmax is modified
0198             gen(igen, QMAX) = Qmin + 0.1 * baseMVA;
0199             warnings{end+1} = sprintf('Qmax = Qmin at generator at bus %4i (Qmax set to Qmin + %g)', bus(ibus, BUS_I), baseMVA/10);
0200             if verbose
0201                 fprintf('    %s\n', warnings{end});
0202             end
0203         end
0204         gen(igen, VG)    = str2num(line(85:90));    % specified voltage
0205         gen(igen, MBASE) = baseMVA;                 % baseMVA
0206         gen(igen, GEN_STATUS) = 1;                  % default status is 'on'
0207         gen(igen, PMAX)  = gen(igen, 2) + baseMVA;  % Pmax
0208         gen(igen, PMIN)  = 0;                       % Pmin = 0 by default
0209 
0210         gencost(igen, MODEL)    = POLYNOMIAL;       % by default, sets the model as polynomial
0211         gencost(igen, STARTUP)  = 0;                % start up cost is zero by default
0212         gencost(igen, SHUTDOWN) = 0;                % shut down cost is zero by default
0213         gencost(igen, NCOST)    = 3;                % number of coefficients in polynomial cost
0214 %       gencost(igen, COST)     = 0.01;             % default c2
0215 %       gencost(igen, COST+1)   = 0.3;              % default c1
0216 %       gencost(igen, COST+2)   = 0.2;              % default c0
0217     end
0218 end
0219 
0220 totload = sum(bus(:, PD));
0221 totgen = sum(gen(:, PG));
0222 if totgen < 1.04 * totload
0223     gen(refgen, PMAX) = gen(refgen, PG) + 1.1 * totload - totgen;   % Pg at slack bus is modified
0224     warnings{end+1} = sprintf('Insufficient generation, setting Pmax at slack bus (bus %d) to %g', gen(refgen, [GEN_BUS, PMAX]));
0225     if verbose
0226         fprintf('    %s\n', warnings{end});
0227     end
0228 end
0229 
0230 % ----- set up the cost coefficients of generators
0231 ng = size(gen, 1);
0232 % gencost(:, COST)    = zeros(ng, 1);
0233 % gencost(:, COST+1)  = 100*ones(ng, 1) ./ (gen(:, PG) + 10*ones(ng, 1));
0234 % gencost(:, COST+2)  = 100*ones(ng, 1) ./ (gen(:, PG) + 10*ones(ng, 1));
0235 zg  = find(gen(:, PG) == 0);                %% for Pg = 0
0236 gencost(zg, COST)  = 0.01 * ones(size(zg));
0237 gencost(zg, COST+1) = 40 * ones(size(zg));
0238 nzg = find(gen(:, PG) ~= 0);                %% Pg non-zero
0239 gencost(nzg, COST) = 10 * ones(size(nzg)) ./ gen(nzg, PG);
0240 gencost(nzg, COST+1) = 20 * ones(size(nzg));
0241 gencost(:, COST+2) = zeros(ng, 1);
0242 
0243 % find string 'BRANCH DATA FOLLOWS'
0244 while 1
0245     line = fgetl(fid);
0246     if line(1:19) == 'BRANCH DATA FOLLOWS', break, end
0247 end
0248 
0249 % ----- get branch data, feed them into matrix branch
0250 k = 0;
0251 while 1
0252     line = fgetl(fid);
0253     if line(1:4) == '-999', break, end
0254 
0255     k = k + 1;
0256     branch(k, F_BUS)  = str2num(line(1:4));     % fbus (also the tap bus)
0257     branch(k, T_BUS)  = str2num(line(6:9));     % tbus
0258     branch(k, BR_R)   = str2num(line(20:29));   % R
0259     branch(k, BR_X)   = str2num(line(30:40));   % X
0260     branch(k, BR_B)   = str2num(line(41:50));   % B
0261     branch(k, RATE_A) = str2num(line(51:55));   % RATE A
0262     if branch(k, RATE_A) < 0.000001
0263         branch(k, RATE_A) = 0;                  % RATE A is modified
0264         warnings{end+1} = sprintf('MVA limit of branch %d - %d not given, set to %g', branch(k, [F_BUS, T_BUS, RATE_A]));
0265         if verbose
0266             fprintf('    %s\n', warnings{end});
0267         end
0268     end
0269     branch(k, RATE_B) = str2num(line(57:61));   % RATE B
0270     branch(k, RATE_C) = str2num(line(63:67));   % RATE C
0271     branch(k, TAP)    = str2num(line(77:82));   % transformer turns ratio
0272     branch(k, SHIFT)  = 0;                      % phase shifter can not be modelled
0273     branch(k, BR_STATUS) = 1;                   % by default, branch is on
0274 end
0275 if verbose
0276     fprintf('Done.\n');
0277 end
0278 fclose(fid);
0279 
0280 % put in struct
0281 mpc.baseMVA = baseMVA;
0282 mpc.bus     = bus;
0283 mpc.branch  = branch;
0284 mpc.gen     = gen;
0285 mpc.gencost = gencost;
0286 mpc.bus_name = bus_name;
0287 mpc = loadcase(mpc);    %% convert to internal (e.g. v. '2') case format
0288 
0289 %% (optionally) save MATPOWER case file
0290 if ~isempty(mpc_name)
0291     comments = {''};
0292     if ~isempty(title_cdf)
0293         comments{end+1} = sprintf('   %s', title_cdf);
0294     end
0295     comments{end+1} = '';
0296     comments{end+1} = sprintf('   Converted by MATPOWER %s using CDF2MPC on %s', mpver, date);
0297     comments{end+1} = sprintf('   from ''%s''.', cdf_file_name);
0298 
0299     %% warnings
0300     comments{end+1} = '';
0301     comments{end+1} = '   WARNINGS:';
0302     for k = 1:length(warnings)
0303         comments{end+1} = sprintf('       %s', warnings{k});
0304     end
0305     comments{end+1} = '';
0306     comments{end+1} = sprintf('   See CASEFORMAT for details on the MATPOWER case file format.');
0307 
0308     if verbose
0309         spacers = repmat('.', 1, 45-length(mpc_name));
0310         fprintf('Saving to MATPOWER case ''%s'' %s', mpc_name, spacers);
0311     end
0312     savecase(mpc_name, comments, mpc);
0313     if verbose
0314         fprintf(' done.\n');
0315     end
0316 end

Generated on Mon 26-Jan-2015 15:21:31 by m2html © 2005