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 vflag = '';
0138 if str2double(version('-release')) > 13
0139 vflag = '-v6';
0140 end
0141 if strcmp(mpc_ver, '1')
0142 if exist('areas', 'var') && exist('gencost', 'var')
0143 save(fname, 'baseMVA', 'bus', 'gen', 'branch', 'areas', 'gencost', vflag);
0144 else
0145 save(fname, 'baseMVA', 'bus', 'gen', 'branch', vflag);
0146 end
0147 else
0148 save(fname, 'baseMVA', 'mpc', vflag);
0149 end
0150 else
0151
0152 [fd, msg] = fopen(fname, 'wt');
0153 if fd == -1
0154 error(['savecase: ', msg]);
0155 end
0156
0157
0158 if strcmp(mpc_ver, '1')
0159 if exist('areas', 'var') && exist('gencost', 'var') && ~isempty(gencost)
0160 fprintf(fd, 'function [baseMVA, bus, gen, branch, areas, gencost] = %s\n', fcn_name);
0161 else
0162 fprintf(fd, 'function [baseMVA, bus, gen, branch] = %s\n', fcn_name);
0163 end
0164 prefix = '';
0165 else
0166 fprintf(fd, 'function mpc = %s\n', fcn_name);
0167 prefix = 'mpc.';
0168 end
0169 if isempty(comment{1})
0170 comment{1} = sprintf('%s', upper(fcn_name));
0171 else
0172 comment{1} = sprintf('%s %s', upper(fcn_name), comment{1});
0173 end
0174 for k = 1:length(comment)
0175 fprintf(fd, '%%%s\n', comment{k});
0176 end
0177 fprintf(fd, '\n%%%% MATPOWER Case Format : Version %s\n', mpc_ver);
0178 if ~strcmp(mpc_ver, '1')
0179 fprintf(fd, 'mpc.version = ''%s'';\n', mpc_ver);
0180 end
0181 fprintf(fd, '\n%%%%----- Power Flow Data -----%%%%\n');
0182 fprintf(fd, '%%%% system MVA base\n');
0183 fprintf(fd, '%sbaseMVA = %.9g;\n', prefix, baseMVA);
0184
0185
0186 ncols = size(bus, 2);
0187 fprintf(fd, '\n%%%% bus data\n');
0188 fprintf(fd, '%%\tbus_i\ttype\tPd\tQd\tGs\tBs\tarea\tVm\tVa\tbaseKV\tzone\tVmax\tVmin');
0189 if ncols >= MU_VMIN
0190 fprintf(fd, '\tlam_P\tlam_Q\tmu_Vmax\tmu_Vmin');
0191 end
0192 fprintf(fd, '\n%sbus = [\n', prefix);
0193 if ncols < MU_VMIN
0194 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).');
0195 else
0196 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).');
0197 end
0198 fprintf(fd, '];\n');
0199
0200
0201 ncols = size(gen, 2);
0202 fprintf(fd, '\n%%%% generator data\n');
0203 fprintf(fd, '%%\tbus\tPg\tQg\tQmax\tQmin\tVg\tmBase\tstatus\tPmax\tPmin');
0204 if ~strcmp(mpc_ver, '1')
0205 fprintf(fd, '\tPc1\tPc2\tQc1min\tQc1max\tQc2min\tQc2max\tramp_agc\tramp_10\tramp_30\tramp_q\tapf');
0206 end
0207 if ncols >= MU_QMIN
0208 fprintf(fd, '\tmu_Pmax\tmu_Pmin\tmu_Qmax\tmu_Qmin');
0209 end
0210 fprintf(fd, '\n%sgen = [\n', prefix);
0211 if ncols < MU_QMIN
0212 if strcmp(mpc_ver, '1')
0213 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).');
0214 else
0215 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).');
0216 end
0217 else
0218 if strcmp(mpc_ver, '1')
0219 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).');
0220 else
0221 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).');
0222 end
0223 end
0224 fprintf(fd, '];\n');
0225
0226
0227 ncols = size(branch, 2);
0228 fprintf(fd, '\n%%%% branch data\n');
0229 fprintf(fd, '%%\tfbus\ttbus\tr\tx\tb\trateA\trateB\trateC\tratio\tangle\tstatus');
0230 if ~strcmp(mpc_ver, '1')
0231 fprintf(fd, '\tangmin\tangmax');
0232 end
0233 if ncols >= QT
0234 fprintf(fd, '\tPf\tQf\tPt\tQt');
0235 end
0236 if ncols >= MU_ST
0237 fprintf(fd, '\tmu_Sf\tmu_St');
0238 if ~strcmp(mpc_ver, '1')
0239 fprintf(fd, '\tmu_angmin\tmu_angmax');
0240 end
0241 end
0242 fprintf(fd, '\n%sbranch = [\n', prefix);
0243 if ncols < QT
0244 if strcmp(mpc_ver, '1')
0245 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).');
0246 else
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%.9g\t%.9g;\n', branch(:, 1:ANGMAX).');
0248 end
0249 elseif ncols < MU_ST
0250 if strcmp(mpc_ver, '1')
0251 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).');
0252 else
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%.9g\t%.9g\t%.4f\t%.4f\t%.4f\t%.4f;\n', branch(:, 1:QT).');
0254 end
0255 else
0256 if strcmp(mpc_ver, '1')
0257 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).');
0258 else
0259 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).');
0260 end
0261 end
0262 fprintf(fd, '];\n');
0263
0264
0265 if (exist('areas', 'var') && ~isempty(areas)) || ...
0266 (exist('gencost', 'var') && ~isempty(gencost))
0267 fprintf(fd, '\n%%%%----- OPF Data -----%%%%');
0268 end
0269 if exist('areas', 'var') && ~isempty(areas)
0270
0271 fprintf(fd, '\n%%%% area data\n');
0272 fprintf(fd, '%%\tarea\trefbus\n');
0273 fprintf(fd, '%sareas = [\n', prefix);
0274 if ~isempty(areas)
0275 fprintf(fd, '\t%d\t%d;\n', areas(:, 1:2).');
0276 end
0277 fprintf(fd, '];\n');
0278 end
0279 if exist('gencost', 'var') && ~isempty(gencost)
0280
0281 fprintf(fd, '\n%%%% generator cost data\n');
0282 fprintf(fd, '%%\t1\tstartup\tshutdown\tn\tx1\ty1\t...\txn\tyn\n');
0283 fprintf(fd, '%%\t2\tstartup\tshutdown\tn\tc(n-1)\t...\tc0\n');
0284 fprintf(fd, '%sgencost = [\n', prefix);
0285 if ~isempty(gencost)
0286 n1 = 2 * max(gencost(gencost(:, MODEL) == PW_LINEAR, NCOST));
0287 n2 = max(gencost(gencost(:, MODEL) == POLYNOMIAL, NCOST));
0288 n = max([n1; n2]);
0289 if size(gencost, 2) < n + 4
0290 error('savecase: gencost data claims it has more columns than it does');
0291 end
0292 template = '\t%d\t%.9g\t%.9g\t%d';
0293 for i = 1:n
0294 template = [template, '\t%.9g'];
0295 end
0296 template = [template, ';\n'];
0297 fprintf(fd, template, gencost(:, 1:n+4).');
0298 end
0299 fprintf(fd, '];\n');
0300 end
0301
0302 if ~strcmp(mpc_ver, '1')
0303
0304 if (isfield(mpc, 'A') && ~isempty(mpc.A)) || ...
0305 (isfield(mpc, 'N') && ~isempty(mpc.N))
0306 fprintf(fd, '\n%%%%----- Generalized OPF User Data -----%%%%');
0307 end
0308
0309
0310 if isfield(mpc, 'A') && ~isempty(mpc.A)
0311
0312 fprintf(fd, '\n%%%% user constraints\n');
0313 print_sparse(fd, sprintf('%sA', prefix), mpc.A);
0314 if isfield(mpc, 'l') && ~isempty(mpc.l) && ...
0315 isfield(mpc, 'u') && ~isempty(mpc.u)
0316 fprintf(fd, 'lbub = [\n');
0317 fprintf(fd, '\t%.9g\t%.9g;\n', [mpc.l mpc.u].');
0318 fprintf(fd, '];\n');
0319 fprintf(fd, '%sl = lbub(:, 1);\n', prefix);
0320 fprintf(fd, '%su = lbub(:, 2);\n\n', prefix);
0321 elseif isfield(mpc, 'l') && ~isempty(mpc.l)
0322 fprintf(fd, '%sl = [\n', prefix);
0323 fprintf(fd, '\t%.9g;\n', mpc.l);
0324 fprintf(fd, '];\n\n');
0325 elseif isfield(mpc, 'u') && ~isempty(mpc.u)
0326 fprintf(fd, '%su = [\n', prefix);
0327 fprintf(fd, '\t%.9g;\n', mpc.u);
0328 fprintf(fd, '];\n');
0329 end
0330 end
0331
0332
0333 if isfield(mpc, 'N') && ~isempty(mpc.N)
0334 fprintf(fd, '\n%%%% user costs\n');
0335 print_sparse(fd, sprintf('%sN', prefix), mpc.N);
0336 if isfield(mpc, 'H') && ~isempty(mpc.H)
0337 print_sparse(fd, sprintf('%sH', prefix), mpc.H);
0338 end
0339 if isfield(mpc, 'fparm') && ~isempty(mpc.fparm)
0340 fprintf(fd, 'Cw_fparm = [\n');
0341 fprintf(fd, '\t%.9g\t%d\t%.9g\t%.9g\t%.9g;\n', [mpc.Cw mpc.fparm].');
0342 fprintf(fd, '];\n');
0343 fprintf(fd, '%sCw = Cw_fparm(:, 1);\n', prefix);
0344 fprintf(fd, '%sfparm = Cw_fparm(:, 2:5);\n', prefix);
0345 else
0346 fprintf(fd, '%sCw = [\n', prefix);
0347 fprintf(fd, '\t%.9g;\n', mpc.Cw);
0348 fprintf(fd, '];\n');
0349 end
0350 end
0351
0352
0353 if isfield(mpc, 'z0') || isfield(mpc, 'zl') || isfield(mpc, 'zu')
0354 fprintf(fd, '\n%%%% user vars\n');
0355 end
0356 if isfield(mpc, 'z0') && ~isempty(mpc.z0)
0357 fprintf(fd, '%sz0 = [\n', prefix);
0358 fprintf(fd, '\t%.9g;\n', mpc.z0);
0359 fprintf(fd, '];\n');
0360 end
0361 if isfield(mpc, 'zl') && ~isempty(mpc.zl)
0362 fprintf(fd, '%szl = [\n', prefix);
0363 fprintf(fd, '\t%.9g;\n', mpc.zl);
0364 fprintf(fd, '];\n');
0365 end
0366 if isfield(mpc, 'zu') && ~isempty(mpc.zu)
0367 fprintf(fd, '%szu = [\n', prefix);
0368 fprintf(fd, '\t%.9g;\n', mpc.zu);
0369 fprintf(fd, '];\n');
0370 end
0371
0372
0373 if isfield(mpc, 'genfuel') && iscell(mpc.genfuel)
0374 ng = length(mpc.genfuel);
0375 if size(mpc.gen, 1) ~= ng
0376 warning('savecase: genfuel field does not have the expected dimensions (length = %d, expected %d)', ng, size(mpc.gen, 1));
0377 end
0378
0379 fprintf(fd, '\n%%%% generator fuel type\n');
0380 fprintf(fd, '%sgenfuel = {\n', prefix);
0381 for k = 1:ng
0382 fprintf(fd, '\t''%s'';\n', mpc.genfuel{k});
0383 end
0384 fprintf(fd, '};\n');
0385 end
0386
0387
0388 if isfield(mpc, 'bus_name') && iscell(mpc.bus_name)
0389 nb = length(mpc.bus_name);
0390 if size(mpc.bus, 1) ~= nb
0391 warning('savecase: bus_name field does not have the expected dimensions (length = %d, expected %d)', nb, size(mpc.bus, 1));
0392 end
0393
0394 fprintf(fd, '\n%%%% bus names\n');
0395 fprintf(fd, '%sbus_name = {\n', prefix);
0396 for k = 1:nb
0397 fprintf(fd, '\t''%s'';\n', strrep(mpc.bus_name{k}, '''', ''''''));
0398 end
0399 fprintf(fd, '};\n');
0400 end
0401
0402
0403 if isfield(mpc, 'userfcn')
0404 run_userfcn(mpc.userfcn, 'savecase', mpc, fd, prefix);
0405 end
0406 end
0407
0408
0409 if fd ~= 1
0410 fclose(fd);
0411 end
0412 end
0413
0414 if nargout > 0
0415 fname_out = fname;
0416 end
0417
0418
0419
0420 function print_sparse(fd, varname, A)
0421
0422 [i, j, s] = find(A);
0423 [m, n] = size(A);
0424
0425 if isempty(s)
0426 fprintf(fd, '%s = sparse(%d, %d);\n', varname, m, n);
0427 else
0428 fprintf(fd, 'ijs = [\n');
0429 if m == 1
0430 fprintf(fd, '\t%d\t%d\t%.9g;\n', [i; j; s]);
0431 else
0432 fprintf(fd, '\t%d\t%d\t%.9g;\n', [i j s].');
0433 end
0434 fprintf(fd, '];\n');
0435 fprintf(fd, '%s = sparse(ijs(:, 1), ijs(:, 2), ijs(:, 3), %d, %d);\n', varname, m, n);
0436 end