0001 function fname_out = savecase(fname, varargin)
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 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0037 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
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 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0042 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0043 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0044 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0045
0046
0047 if ischar(varargin{1}) || iscell(varargin{1})
0048 if ischar(varargin{1})
0049 comment = {varargin{1}};
0050 else
0051 comment = varargin{1};
0052 end
0053 [args{1:(length(varargin)-1)}] = deal(varargin{2:end});
0054 else
0055 comment = {''};
0056 args = varargin;
0057 end
0058 mpc_ver = '2';
0059 if isstruct(args{1})
0060 mpc = args{1};
0061 if length(args) > 1
0062 mpc.version = args{2};
0063 mpc_ver = mpc.version;
0064 end
0065 baseMVA = mpc.baseMVA;
0066 bus = mpc.bus;
0067 gen = mpc.gen;
0068 branch = mpc.branch;
0069 if isfield(mpc, 'areas')
0070 areas = mpc.areas;
0071 end
0072 if isfield(mpc, 'gencost')
0073 gencost = mpc.gencost;
0074 end
0075 else
0076 baseMVA = args{1};
0077 bus = args{2};
0078 gen = args{3};
0079 branch = args{4};
0080 mpc.baseMVA = baseMVA;
0081 mpc.bus = bus;
0082 mpc.gen = gen;
0083 mpc.branch = branch;
0084 if length(args) == 5
0085 gencost = args{5};
0086 mpc.gencost = gencost;
0087 end
0088 if length(args) == 6
0089 areas = args{5};
0090 gencost = args{6};
0091 mpc.areas = areas;
0092 mpc.gencost = gencost;
0093 end
0094 end
0095
0096
0097 if strcmp(mpc_ver, '1')
0098
0099 if size(gen, 2) >= MU_QMIN
0100 gen = gen(:, [1:PMIN, MU_PMAX:MU_QMIN]);
0101 else
0102 gen = gen(:, 1:PMIN);
0103 end
0104
0105 shift = MU_PMAX - PMIN - 1;
0106 tmp = num2cell([MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN] - shift);
0107 [MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN] = deal(tmp{:});
0108
0109
0110 if size(branch, 2) >= MU_ST
0111 branch = branch(:, [1:BR_STATUS, PF:MU_ST]);
0112 elseif size(branch, 2) >= QT
0113 branch = branch(:, [1:BR_STATUS, PF:QT]);
0114 else
0115 branch = branch(:, 1:BR_STATUS);
0116 end
0117
0118 shift = PF - BR_STATUS - 1;
0119 tmp = num2cell([PF, QF, PT, QT, MU_SF, MU_ST] - shift);
0120 [PF, QF, PT, QT, MU_SF, MU_ST] = deal(tmp{:});
0121 end
0122
0123
0124 [pathstr, fcn_name, extension] = fileparts(fname);
0125 if isempty(extension)
0126 extension = '.m';
0127 end
0128 if regexp(fcn_name, '\W')
0129 old_fcn_name = fcn_name;
0130 fcn_name = regexprep(fcn_name, '\W', '_');
0131 fprintf('WARNING: ''%s'' is not a valid function name, changed to ''%s''\n', old_fcn_name, fcn_name);
0132 end
0133 fname = fullfile(pathstr, [fcn_name extension]);
0134
0135
0136 if strcmp(upper(extension), '.MAT')
0137 if strcmp(mpc_ver, '1')
0138 if exist('areas', 'var') && exist('gencost', 'var')
0139 save(fname, 'baseMVA', 'bus', 'gen', 'branch', 'areas', 'gencost');
0140 else
0141 save(fname, 'baseMVA', 'bus', 'gen', 'branch');
0142 end
0143 else
0144 save(fname, 'baseMVA', 'mpc');
0145 end
0146 else
0147
0148 [fd, msg] = fopen(fname, 'wt');
0149 if fd == -1
0150 error(['savecase: ', msg]);
0151 end
0152
0153
0154 if strcmp(mpc_ver, '1')
0155 if exist('areas', 'var') && exist('gencost', 'var') && ~isempty(gencost)
0156 fprintf(fd, 'function [baseMVA, bus, gen, branch, areas, gencost] = %s\n', fcn_name);
0157 else
0158 fprintf(fd, 'function [baseMVA, bus, gen, branch] = %s\n', fcn_name);
0159 end
0160 prefix = '';
0161 else
0162 fprintf(fd, 'function mpc = %s\n', fcn_name);
0163 prefix = 'mpc.';
0164 end
0165 if isempty(comment{1})
0166 comment{1} = sprintf('%s', upper(fcn_name));
0167 else
0168 comment{1} = sprintf('%s %s', upper(fcn_name), comment{1});
0169 end
0170 for k = 1:length(comment)
0171 fprintf(fd, '%%%s\n', comment{k});
0172 end
0173 fprintf(fd, '\n%%%% MATPOWER Case Format : Version %s\n', mpc_ver);
0174 if ~strcmp(mpc_ver, '1')
0175 fprintf(fd, 'mpc.version = ''%s'';\n', mpc_ver);
0176 end
0177 fprintf(fd, '\n%%%%----- Power Flow Data -----%%%%\n');
0178 fprintf(fd, '%%%% system MVA base\n');
0179 fprintf(fd, '%sbaseMVA = %.9g;\n', prefix, baseMVA);
0180
0181
0182 ncols = size(bus, 2);
0183 fprintf(fd, '\n%%%% bus data\n');
0184 fprintf(fd, '%%\tbus_i\ttype\tPd\tQd\tGs\tBs\tarea\tVm\tVa\tbaseKV\tzone\tVmax\tVmin');
0185 if ncols >= MU_VMIN
0186 fprintf(fd, '\tlam_P\tlam_Q\tmu_Vmax\tmu_Vmin');
0187 end
0188 fprintf(fd, '\n%sbus = [\n', prefix);
0189 if ncols < MU_VMIN
0190 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g;\n', bus(:, 1:VMIN).');
0191 else
0192 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.4f\t%.4f\t%.4f\t%.4f;\n', bus(:, 1:MU_VMIN).');
0193 end
0194 fprintf(fd, '];\n');
0195
0196
0197 ncols = size(gen, 2);
0198 fprintf(fd, '\n%%%% generator data\n');
0199 fprintf(fd, '%%\tbus\tPg\tQg\tQmax\tQmin\tVg\tmBase\tstatus\tPmax\tPmin');
0200 if ~strcmp(mpc_ver, '1')
0201 fprintf(fd, '\tPc1\tPc2\tQc1min\tQc1max\tQc2min\tQc2max\tramp_agc\tramp_10\tramp_30\tramp_q\tapf');
0202 end
0203 if ncols >= MU_QMIN
0204 fprintf(fd, '\tmu_Pmax\tmu_Pmin\tmu_Qmax\tmu_Qmin');
0205 end
0206 fprintf(fd, '\n%sgen = [\n', prefix);
0207 if ncols < MU_QMIN
0208 if strcmp(mpc_ver, '1')
0209 fprintf(fd, '\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g;\n', gen(:, 1:PMIN).');
0210 else
0211 fprintf(fd, '\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g;\n', gen(:, 1:APF).');
0212 end
0213 else
0214 if strcmp(mpc_ver, '1')
0215 fprintf(fd, '\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.4f\t%.4f\t%.4f\t%.4f;\n', gen(:, 1:MU_QMIN).');
0216 else
0217 fprintf(fd, '\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.4f\t%.4f\t%.4f\t%.4f;\n', gen(:, 1:MU_QMIN).');
0218 end
0219 end
0220 fprintf(fd, '];\n');
0221
0222
0223 ncols = size(branch, 2);
0224 fprintf(fd, '\n%%%% branch data\n');
0225 fprintf(fd, '%%\tfbus\ttbus\tr\tx\tb\trateA\trateB\trateC\tratio\tangle\tstatus');
0226 if ~strcmp(mpc_ver, '1')
0227 fprintf(fd, '\tangmin\tangmax');
0228 end
0229 if ncols >= QT
0230 fprintf(fd, '\tPf\tQf\tPt\tQt');
0231 end
0232 if ncols >= MU_ST
0233 fprintf(fd, '\tmu_Sf\tmu_St');
0234 if ~strcmp(mpc_ver, '1')
0235 fprintf(fd, '\tmu_angmin\tmu_angmax');
0236 end
0237 end
0238 fprintf(fd, '\n%sbranch = [\n', prefix);
0239 if ncols < QT
0240 if strcmp(mpc_ver, '1')
0241 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d;\n', branch(:, 1:BR_STATUS).');
0242 else
0243 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g;\n', branch(:, 1:ANGMAX).');
0244 end
0245 elseif ncols < MU_ST
0246 if strcmp(mpc_ver, '1')
0247 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.4f\t%.4f\t%.4f\t%.4f;\n', branch(:, 1:QT).');
0248 else
0249 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.4f\t%.4f\t%.4f\t%.4f;\n', branch(:, 1:QT).');
0250 end
0251 else
0252 if strcmp(mpc_ver, '1')
0253 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f;\n', branch(:, 1:MU_ST).');
0254 else
0255 fprintf(fd, '\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%d\t%.9g\t%.9g\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f;\n', branch(:, 1:MU_ANGMAX).');
0256 end
0257 end
0258 fprintf(fd, '];\n');
0259
0260
0261 if (exist('areas', 'var') && ~isempty(areas)) || ...
0262 (exist('gencost', 'var') && ~isempty(gencost))
0263 fprintf(fd, '\n%%%%----- OPF Data -----%%%%');
0264 end
0265 if exist('areas', 'var') && ~isempty(areas)
0266
0267 fprintf(fd, '\n%%%% area data\n');
0268 fprintf(fd, '%%\tarea\trefbus\n');
0269 fprintf(fd, '%sareas = [\n', prefix);
0270 if ~isempty(areas)
0271 fprintf(fd, '\t%d\t%d;\n', areas(:, 1:2).');
0272 end
0273 fprintf(fd, '];\n');
0274 end
0275 if exist('gencost', 'var') && ~isempty(gencost)
0276
0277 fprintf(fd, '\n%%%% generator cost data\n');
0278 fprintf(fd, '%%\t1\tstartup\tshutdown\tn\tx1\ty1\t...\txn\tyn\n');
0279 fprintf(fd, '%%\t2\tstartup\tshutdown\tn\tc(n-1)\t...\tc0\n');
0280 fprintf(fd, '%sgencost = [\n', prefix);
0281 if ~isempty(gencost)
0282 n1 = 2 * max(gencost(gencost(:, MODEL) == PW_LINEAR, NCOST));
0283 n2 = max(gencost(gencost(:, MODEL) == POLYNOMIAL, NCOST));
0284 n = max([n1; n2]);
0285 if size(gencost, 2) < n + 4
0286 error('savecase: gencost data claims it has more columns than it does');
0287 end
0288 template = '\t%d\t%.9g\t%.9g\t%d';
0289 for i = 1:n
0290 template = [template, '\t%.9g'];
0291 end
0292 template = [template, ';\n'];
0293 fprintf(fd, template, gencost(:, 1:n+4).');
0294 end
0295 fprintf(fd, '];\n');
0296 end
0297
0298 if ~strcmp(mpc_ver, '1')
0299
0300 if (isfield(mpc, 'A') && ~isempty(mpc.A)) || ...
0301 (isfield(mpc, 'N') && ~isempty(mpc.N))
0302 fprintf(fd, '\n%%%%----- Generalized OPF User Data -----%%%%');
0303 end
0304
0305
0306 if isfield(mpc, 'A') && ~isempty(mpc.A)
0307
0308 fprintf(fd, '\n%%%% user constraints\n');
0309 print_sparse(fd, sprintf('%sA', prefix), mpc.A);
0310 if isfield(mpc, 'l') && ~isempty(mpc.l) && ...
0311 isfield(mpc, 'u') && ~isempty(mpc.u)
0312 fprintf(fd, 'lbub = [\n');
0313 fprintf(fd, '\t%.9g\t%.9g;\n', [mpc.l mpc.u].');
0314 fprintf(fd, '];\n');
0315 fprintf(fd, '%sl = lbub(:, 1);\n', prefix);
0316 fprintf(fd, '%su = lbub(:, 2);\n\n', prefix);
0317 elseif isfield(mpc, 'l') && ~isempty(mpc.l)
0318 fprintf(fd, '%sl = [\n', prefix);
0319 fprintf(fd, '\t%.9g;\n', mpc.l);
0320 fprintf(fd, '];\n\n');
0321 elseif isfield(mpc, 'u') && ~isempty(mpc.u)
0322 fprintf(fd, '%su = [\n', prefix);
0323 fprintf(fd, '\t%.9g;\n', mpc.u);
0324 fprintf(fd, '];\n');
0325 end
0326 end
0327
0328
0329 if isfield(mpc, 'N') && ~isempty(mpc.N)
0330 fprintf(fd, '\n%%%% user costs\n');
0331 print_sparse(fd, sprintf('%sN', prefix), mpc.N);
0332 if isfield(mpc, 'H') && ~isempty(mpc.H)
0333 print_sparse(fd, sprintf('%sH', prefix), mpc.H);
0334 end
0335 if isfield(mpc, 'fparm') && ~isempty(mpc.fparm)
0336 fprintf(fd, 'Cw_fparm = [\n');
0337 fprintf(fd, '\t%.9g\t%d\t%.9g\t%.9g\t%.9g;\n', [mpc.Cw mpc.fparm].');
0338 fprintf(fd, '];\n');
0339 fprintf(fd, '%sCw = Cw_fparm(:, 1);\n', prefix);
0340 fprintf(fd, '%sfparm = Cw_fparm(:, 2:5);\n', prefix);
0341 else
0342 fprintf(fd, '%sCw = [\n', prefix);
0343 fprintf(fd, '\t%.9g;\n', mpc.Cw);
0344 fprintf(fd, '];\n');
0345 end
0346 end
0347
0348
0349 if isfield(mpc, 'z0') || isfield(mpc, 'zl') || isfield(mpc, 'zu')
0350 fprintf(fd, '\n%%%% user vars\n');
0351 end
0352 if isfield(mpc, 'z0') && ~isempty(mpc.z0)
0353 fprintf(fd, '%sz0 = [\n', prefix);
0354 fprintf(fd, '\t%.9g;\n', mpc.z0);
0355 fprintf(fd, '];\n');
0356 end
0357 if isfield(mpc, 'zl') && ~isempty(mpc.zl)
0358 fprintf(fd, '%szl = [\n', prefix);
0359 fprintf(fd, '\t%.9g;\n', mpc.zl);
0360 fprintf(fd, '];\n');
0361 end
0362 if isfield(mpc, 'zu') && ~isempty(mpc.zu)
0363 fprintf(fd, '%szu = [\n', prefix);
0364 fprintf(fd, '\t%.9g;\n', mpc.zu);
0365 fprintf(fd, '];\n');
0366 end
0367
0368
0369 if isfield(mpc, 'gentype') && iscell(mpc.gentype)
0370 ng = length(mpc.gentype);
0371 if size(mpc.gen, 1) ~= ng
0372 warning('savecase: gentype field does not have the expected dimensions (length = %d, expected %d)', ng, size(mpc.gen, 1));
0373 end
0374
0375 fprintf(fd, '\n%%%% generator unit type (see GENTYPES)\n');
0376 fprintf(fd, '%sgentype = {\n', prefix);
0377 for k = 1:ng
0378 fprintf(fd, '\t''%s'';\n', mpc.gentype{k});
0379 end
0380 fprintf(fd, '};\n');
0381 end
0382
0383
0384 if isfield(mpc, 'genfuel') && iscell(mpc.genfuel)
0385 ng = length(mpc.genfuel);
0386 if size(mpc.gen, 1) ~= ng
0387 warning('savecase: genfuel field does not have the expected dimensions (length = %d, expected %d)', ng, size(mpc.gen, 1));
0388 end
0389
0390 fprintf(fd, '\n%%%% generator fuel type (see GENFUELS)\n');
0391 fprintf(fd, '%sgenfuel = {\n', prefix);
0392 for k = 1:ng
0393 fprintf(fd, '\t''%s'';\n', mpc.genfuel{k});
0394 end
0395 fprintf(fd, '};\n');
0396 end
0397
0398
0399 if isfield(mpc, 'bus_name') && iscell(mpc.bus_name)
0400 nb = length(mpc.bus_name);
0401 if size(mpc.bus, 1) ~= nb
0402 warning('savecase: bus_name field does not have the expected dimensions (length = %d, expected %d)', nb, size(mpc.bus, 1));
0403 end
0404
0405 fprintf(fd, '\n%%%% bus names\n');
0406 fprintf(fd, '%sbus_name = {\n', prefix);
0407 for k = 1:nb
0408 fprintf(fd, '\t''%s'';\n', strrep(mpc.bus_name{k}, '''', ''''''));
0409 end
0410 fprintf(fd, '};\n');
0411 end
0412
0413
0414 if isfield(mpc, 'userfcn')
0415 run_userfcn(mpc.userfcn, 'savecase', mpc, fd, prefix);
0416 end
0417 end
0418
0419
0420 if fd ~= 1
0421 fclose(fd);
0422 end
0423 end
0424
0425 if nargout > 0
0426 fname_out = fname;
0427 end
0428
0429
0430
0431 function print_sparse(fd, varname, A)
0432
0433 [i, j, s] = find(A);
0434 [m, n] = size(A);
0435
0436 if isempty(s)
0437 fprintf(fd, '%s = sparse(%d, %d);\n', varname, m, n);
0438 else
0439 fprintf(fd, 'ijs = [\n');
0440 if m == 1
0441 fprintf(fd, '\t%d\t%d\t%.9g;\n', [i; j; s]);
0442 else
0443 fprintf(fd, '\t%d\t%d\t%.9g;\n', [i j s].');
0444 end
0445 fprintf(fd, '];\n');
0446 fprintf(fd, '%s = sparse(ijs(:, 1), ijs(:, 2), ijs(:, 3), %d, %d);\n', varname, m, n);
0447 end