Home > matpower7.1 > lib > save2psse.m

save2psse

PURPOSE ^

SAVE2PSSE Saves a MATPOWER case to PSS/E RAW format.

SYNOPSIS ^

function fname_out = save2psse(fname, mpc, rawver)

DESCRIPTION ^

SAVE2PSSE  Saves a MATPOWER case to PSS/E RAW format.
   SAVE2PSSE(FNAME, MPC)

   FNAME = SAVE2PSSE(FNAME, ...)

   Saves a MATPOWER case struct MPC as a PSS/E RAW file. The FNAME
   parameter is a string containing the name of the file to be created
   or overwritten. If FNAME does not include a file extension, '.raw'
   will be added. Optionally returns the, possibly updated, filename.
   Currently exports to RAW format Rev 33.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function fname_out = save2psse(fname, mpc, rawver)
0002 %SAVE2PSSE  Saves a MATPOWER case to PSS/E RAW format.
0003 %   SAVE2PSSE(FNAME, MPC)
0004 %
0005 %   FNAME = SAVE2PSSE(FNAME, ...)
0006 %
0007 %   Saves a MATPOWER case struct MPC as a PSS/E RAW file. The FNAME
0008 %   parameter is a string containing the name of the file to be created
0009 %   or overwritten. If FNAME does not include a file extension, '.raw'
0010 %   will be added. Optionally returns the, possibly updated, filename.
0011 %   Currently exports to RAW format Rev 33.
0012 
0013 %   To do:
0014 %   SAVE2PSSE(FNAME, CASESTRUCT, VERSION) (not yet implmented)
0015 
0016 %   MATPOWER
0017 %   Copyright (c) 2017 Power Systems Engineering Research Center (PSERC)
0018 %   by Ray Zimmerman, PSERC Cornell
0019 %
0020 %   This file is part of MATPOWER.
0021 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0022 %   See https://matpower.org for more info.
0023 
0024 %% define named indices into bus, gen, branch matrices
0025 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0026     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0027 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0028     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0029     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0030 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0031     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0032     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0033 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0034 c = idx_dcline;
0035 
0036 %% verify valid filename
0037 [pathstr, fcn_name, extension] = fileparts(fname);
0038 if isempty(extension)
0039     extension = '.raw';
0040 end
0041 fname = fullfile(pathstr, [fcn_name extension]);
0042 
0043 %% open file
0044 [fd, msg] = fopen(fname, 'wt');     %% print it to a text file
0045 if fd == -1
0046     error(['save2psse: ', msg]);
0047 end
0048 
0049 %% create map of external bus numbers to bus indices
0050 i2e = mpc.bus(:, BUS_I);
0051 e2i = sparse(max(i2e), 1);
0052 e2i(i2e) = (1:size(mpc.bus, 1))';
0053 
0054 %% Case Identification Data
0055 fprintf(fd, '0, %d, 33, 0, 0, 60  / %s - MATPOWER %s\n', mpc.baseMVA, datestr(clock), mpver);
0056 fprintf(fd, '\n');
0057 fprintf(fd, '\n');
0058 
0059 %% Bus Data
0060 nb = size(mpc.bus, 1);  %% number of buses
0061 if isfield(mpc, 'bus_name')
0062     maxlen = max(cellfun(@length, mpc.bus_name));
0063     tmp = cell2mat(cellfun( @(s)sprintf('%-*s', max(maxlen, 12), s), ...
0064                             mpc.bus_name, 'UniformOutput', 0 ));
0065     bn = tmp(:, 1:12);
0066 else
0067     bn = cell2mat(cellfun( @(s)sprintf('BUS %-8d', s), ...
0068                            num2cell(mpc.bus(:, BUS_I)), 'UniformOutput', 0 ));
0069 end
0070 %%             I,                       'NAME',BASEKV,IDE,AREA,ZONE,OWNER,   VM,    VA,NVHI, NVLO, EVHI, EVLO
0071 fprintf(fd, '%6d, ''%c%c%c%c%c%c%c%c%c%c%c%c'', %9.7g, %d, %4d, %4d, %d, %11.9g, %11.9g, %4g, %4g, %4g, %4g\n', ...
0072     [ mpc.bus(:, BUS_I) double(bn) ...
0073       mpc.bus(:, [BASE_KV BUS_TYPE BUS_AREA ZONE]) ones(nb, 1) ...
0074       mpc.bus(:, [VM VA VMAX VMIN VMAX VMIN]) ...
0075     ]');
0076 fprintf(fd, '0 / END OF BUS DATA, BEGIN LOAD DATA\n');
0077 
0078 %% Load Data
0079 ild = find(mpc.bus(:, PD) ~= 0 | mpc.bus(:, PD) ~= 0);  %% bus indices of fixed loads
0080 nld = length(ild);
0081 if nld
0082     %%             I, ID,STATUS,AREA,ZONE, PL,   QL,   IP,   IQ,   YP,   YQ,OWNER, SCALE, INTRPT
0083     fprintf(fd, '%6d, %2d, %d, %4d, %4d, %9.7g, %9.7g, %.9g, %.9g, %.9g, %.9g, %d, %d, %d\n', ...
0084         [ mpc.bus(ild, BUS_I) ones(nld, 2) ...
0085           mpc.bus(ild, [BUS_AREA ZONE PD QD]) ...
0086           zeros(nld, 4) ones(nld, 2) zeros(nld, 1) ...
0087         ]');
0088 end
0089 idl = find(isload(mpc.gen));        %% gen indices of dispatchable loads
0090 ndl = length(idl);
0091 ib = e2i(mpc.gen(idl, GEN_BUS));    %% bus indices corresponding to dispatchable loads
0092 if ndl
0093     %%             I, ID,STATUS,AREA,ZONE, PL,   QL,   IP,   IQ,   YP,   YQ,OWNER, SCALE, INTRPT
0094     fprintf(fd, '%6d, %2d, %d, %4d, %4d, %9.7g, %9.7g, %.9g, %.9g, %.9g, %.9g, %d, %d, %d\n', ...
0095         [ mpc.bus(ib, BUS_I) ones(nld, 2) mpc.bus(ib, [BUS_AREA ZONE]) ...
0096           -mpc.gen(idl, [PMIN QMIN]) ...
0097           zeros(nld, 4) ones(nld, 3) ...
0098         ]');
0099 end
0100 %%----- TODO: add correct ID value for multiple loads at a bus
0101 fprintf(fd, '0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA\n');
0102 
0103 %% Fixed Bus Shunt Data
0104 ifs = find(mpc.bus(:, GS) ~= 0 | mpc.bus(:, BS) ~= 0);
0105 nfs = length(ifs);
0106 if nfs
0107     %%             I, ID,STATUS,GL, BL
0108     fprintf(fd, '%6d, %d, %d, %7g, %7g\n', ...
0109         [ mpc.bus(ifs, BUS_I) ones(nfs, 2) mpc.bus(ifs, [GS BS]) ]');
0110 end
0111 fprintf(fd, '0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA\n');
0112 
0113 %% Generator Data
0114 ig = find(~isload(mpc.gen));    %% gen indices (of real generators)
0115 ng = length(ig);
0116 wind = zeros(ng, 1);
0117 if isfield(mpc, 'gentype')
0118     iw = find(cellfun(@(s)strcmp(s,'wind'), mpc.genfuel));
0119     wind(iw) = 1;
0120 end
0121 if isfield(mpc, 'genfuel')
0122     iw = find(cellfun(@(s)strcmp(s(1),'W'), mpc.gentype));
0123     wind(iw) = 1;
0124 end
0125 if ng
0126     %%             I,  ID,    PG,    QG,    QT,    QB,    VS,IREG,MBASE,ZR,ZX, RT, XT,GTAP,STAT,RMPCT,PT,PB,O1,F1,...,O4,F4,WMOD,WPF
0127     fprintf(fd, '%6d, %2d, %9.7g, %9.7g, %9.7g, %9.7g, %8.7g, %d, %7g, %g, %g, %g, %g, %g, %d, %g, %9.7g, %9.7g, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n', ...
0128         [ mpc.gen(ig, GEN_BUS) ones(ng, 1) mpc.gen(ig, [PG QG QMAX QMIN VG]) ...
0129           zeros(ng, 1) mpc.gen(ig, MBASE) zeros(ng, 1) ones(ng, 1) ...
0130           zeros(ng, 2) ones(ng, 1) (mpc.gen(ig, GEN_STATUS) > 0) ...
0131           100*ones(ng, 1) mpc.gen(ig, [PMAX PMIN]) ones(ng, 2) ...
0132           zeros(ng, 1) ones(ng, 1) zeros(ng, 1) ones(ng, 1) ...
0133           zeros(ng, 1) ones(ng, 1) wind ones(ng, 1) ...
0134         ]');
0135 end
0136 %%----- TODO: add correct ID value for multiple generators at a bus
0137 fprintf(fd, '0 / END OF GENERATOR DATA, BEGIN BRANCH DATA\n');
0138 
0139 %% Non-Transformer Branch Data
0140 il = find(mpc.branch(:, TAP) == 0 & mpc.branch(:, SHIFT) == 0);    %% branch indices (of non-transformers)
0141 nl = length(il);
0142 if nl
0143     %%             I,   J,CKT,     R,     X,     B,RATEA,RATEB,RATEC,GI,BI,GJ, BJ, ST,MET,LEN, O1, F1,...,             O4, F4
0144     fprintf(fd, '%6d, %6d, %d, %8.7g, %8.7g, %8.7g, %7g, %7g, %7g, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n', ...
0145         [ mpc.branch(il, [F_BUS T_BUS]) ...
0146           generate_ckt_num(mpc.branch(il, [F_BUS T_BUS])) ...
0147           mpc.branch(il, [BR_R BR_X BR_B RATE_A RATE_B RATE_C]) ...
0148           zeros(nl, 4) mpc.branch(il, [BR_STATUS]) ones(nl, 1) ...
0149           zeros(nl, 1) ones(nl, 2) zeros(nl, 1) ones(nl, 1) ...
0150           zeros(nl, 1) ones(nl, 1) zeros(nl, 1) ones(nl, 1) ...
0151         ]');
0152 end
0153 fprintf(fd, '0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA\n');
0154 
0155 %% Transformer Data
0156 it = find(mpc.branch(:, TAP) ~= 0 | mpc.branch(:, SHIFT) ~= 0);    %% branch indices (of transformers)
0157 nt = length(it);
0158 if nt
0159     %%                                                                                                                                       (skipping R2-3,X2-3,SBASE2-3,R3-1,X3-1,SBASE3-1,VMSTAR,ANSTAR on line 2)          (skipping ANG2,RATA2,RATB2,RATC2,COD2,CONT2,RMA2,RMI2,VMA2,VMI2,NTP2,TAB2,CR2,CX2,CNXA2 on line 4)
0160     %%             I,   J,  K,CKT, CW, CZ, CM,   MAG2,               'NAME',     O1, F1, O2, F2, O3, F3, O4, F4,           VECGRP\n  X1-2,   NOMV1,ANG1,        RATB1,    COD1,   RMA1,   VMA1,   NTP1,    CR1,CX1,  WINDV2,
0161     %%                                       MAG1,  NMETR,                 STAT,                                                R1-2,SBASE1-2\n      WINDV1,RATA1,   RATC1,  CONT1,   RMI1,   VMI1,   TAB1,      CNXA1\n  NOMV2\n
0162     fprintf(fd, '%6d, %6d, %d, %d, %d, %d, %d, %d, %d, %d, ''            '', %d, %d, %d, %d, %d, %d, %d, %d, %d, ''            ''\n%g, %g, %g\n%5g, %d, %5g, %7g, %7g, %7g, %d, %d, %g, %g, %g, %g, %d, %d, %g, %g, %g\n%5g, %g\n', ...
0163         [ mpc.branch(it, [F_BUS T_BUS]) zeros(nt, 1) ...
0164           generate_ckt_num(mpc.branch(it, [F_BUS T_BUS])) ones(nt, 3) ...
0165           zeros(nt, 2) 2*ones(nt, 1) mpc.branch(it, BR_STATUS) ones(nt, 2) ...
0166           zeros(nt, 1) ones(nt, 1) zeros(nt, 1) ones(nt, 1) ...
0167           zeros(nt, 1) ones(nt, 1) ...      %% end of line 1
0168           mpc.branch(it, [BR_R BR_X]) mpc.baseMVA*ones(nt, 1) ...
0169           mpc.branch(it, TAP) zeros(nt, 1) mpc.branch(it, SHIFT) ...
0170           mpc.branch(it, [RATE_A RATE_B RATE_C]) zeros(nt, 2) ...
0171           1.1*ones(nt, 1) 0.9*ones(nt, 1) 1.1*ones(nt, 1) 0.9*ones(nt, 1) ...
0172           33*ones(nt, 1) zeros(nt, 4) ...
0173           ones(nt, 1) zeros(nt, 1) ...
0174         ]');
0175 end
0176 fprintf(fd, '0 / END OF TRANSFORMER DATA, BEGIN AREA DATA\n');
0177 
0178 %% Area Interchange Data
0179 %% I, ISW, PDES, PTOL, 'ARNAME'
0180 fprintf(fd, '0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA\n');
0181 
0182 %% Two-Terminal DC Transmission Line Data
0183 if isfield(mpc, 'dcline')
0184     ndc = size(mpc.dcline, 1);
0185     if ndc
0186         dn = cell2mat(cellfun(  @(s)sprintf('DCLINE %-5d', s), ...
0187                                 num2cell((1:ndc)'), 'UniformOutput', 0 ));
0188         %%                                                                                             IPR,NBR,ANMXR,ANMNR,RCR,XCR,EBASR,TRR,TAPR,TMXR,TMNR,    STPR,ICR,IFR,ITR,IDR,XCAPR
0189         %%                                'NAME',MDC, RDC, SETVL,VSCHD,VCMOD,RCOMP,DELTI,METER,DCVMIN,CCCITMX,CCCACC                                                                       IPI,NBI,ANMXI,ANMNI,RCI,XCI,EBASI,TRI,TAPI,TMXI,TMNI,STPI,ICI,IFI,ITI,IDI,XCAPI
0190         fprintf(fd, '''%c%c%c%c%c%c%c%c%c%c%c%c'', 1, 0.0, %9.7g, 500, 0.0, 0.0, 0.0, I, 0.0, 20, 1.0\n%6d, 1, 25.0, 15.0, 0, 0, %8.7g, 1.0, 1.0, 1.5, 0.51, 0.00625, 0, 0, 0, ''1'', 0.0\n%6d, 1, 25.0, 15.0, 0, 0, %8.7g, 1.0, 1.0, 1.5, 0.51, 0.00625, 0, 0, 0, ''1'', 0.0\n', ...
0191             [ double(dn) mpc.dcline(:, c.PF) ...
0192               mpc.dcline(:, c.F_BUS) ...
0193               mpc.bus(e2i(mpc.dcline(:, c.F_BUS)), BASE_KV) ...
0194               mpc.dcline(:, c.T_BUS) ...
0195               mpc.bus(e2i(mpc.dcline(:, c.T_BUS)), BASE_KV) ...
0196             ]');
0197     end
0198 end
0199 %%----- TODO: attempt some values to approximate losses
0200 fprintf(fd, '0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA\n');
0201 
0202 %% Voltage Source Converter (VSC) DC Transmission Line Data
0203 %% 'NAME', MDC, RDC, O1, F1, ... O4, F4
0204 %% IBUS,TYPE,MODE,DCSET,ACSET,ALOSS,BLOSS,MINLOSS,SMAX,IMAX,PWF,MAXQ,MINQ,REMOT,RMPCT
0205 %% IBUS,TYPE,MODE,DCSET,ACSET,ALOSS,BLOSS,MINLOSS,SMAX,IMAX,PWF,MAXQ,MINQ,REMOT,RMPCT
0206 fprintf(fd, '0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA\n');
0207 
0208 %% Transformer Impedance Correction Tables
0209 %% I, T1, F1, T2, F2, T3, F3, ... T11, F11
0210 fprintf(fd, '0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA\n');
0211 
0212 %% Multi-Terminal DC Transmission Line Data
0213 %% 'NAME', NCONV, NDCBS, NDCLN, MDC, VCONV, VCMOD, VCONVN
0214 %% IB,N,ANGMX,ANGMN,RC,XC,EBAS,TR,TAP,TPMX,TPMN,TSTP,SETVL,DCPF,MARG,CNVCOD
0215 %% IDC, IB, AREA, ZONE, 'DCNAME', IDC2, RGRND, OWNER
0216 %% IDC, JDC, DCCKT, MET, RDC, LDC
0217 fprintf(fd, '0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA\n');
0218 
0219 %% Multi-Section Line Grouping Data
0220 %% I, J, ID, MET, DUM1, DUM2, ... DUM9
0221 fprintf(fd, '0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA\n');
0222 
0223 %% Zone Data
0224 %% I, 'ZONAME'
0225 fprintf(fd, '0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA\n');
0226 
0227 %% Interarea Transfer Data
0228 %% ARFROM, ARTO, TRID, PTRAN
0229 fprintf(fd, '0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA\n');
0230 
0231 %% Owner Data
0232 %% I, 'OWNAME'
0233 fprintf(fd, '0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA\n');
0234 
0235 %% FACTS Device Data
0236 %% 'NAME',I,J,MODE,PDES,QDES,VSET,SHMX,TRMX,VTMN,VTMX,VSMX,IMX,LINX,RMPCT,OWNER,SET1,SET2,VSREF,REMOT,'MNAME'
0237 fprintf(fd, '0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA\n');
0238 
0239 %% Switched Shunt Data
0240 %% I, MODSW, ADJM, STAT, VSWHI, VSWLO, SWREM, RMPCT, 'RMIDNT', BINIT, N1, B1, N2, B2, ... N8, B8
0241 fprintf(fd, '0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA\n');
0242 
0243 %% GNE Device Data
0244 fprintf(fd, '0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA\n');
0245 
0246 %% Induction Machine Data
0247 fprintf(fd, '0 / END OF INDUCTION MACHINE DATA\n');
0248 
0249 %% End of Data Indicator
0250 fprintf(fd, 'Q\n');
0251 
0252 %% close file
0253 if fd ~= 1
0254     fclose(fd);
0255 end
0256 
0257 if nargout > 0
0258     fname_out = fname;
0259 end
0260 
0261 
0262 function ckt = generate_ckt_num(ft, ckt)
0263 % returns a vector of circuit numbers given a 2-col matrix of from/to bus nums
0264 % where duplicate pairs get incremented ckt numbers
0265 n = size(ft, 1);
0266 if nargin < 2
0267     ckt = zeros(n, 1);
0268 end
0269 ckt = ckt + 1;
0270 [Au, iA, iAu] = unique(ft, 'rows', 'first');
0271 k = find(~ismember([1:n]', iA));
0272 if k
0273     ckt(k) = generate_ckt_num(ft(k, :), ckt(k));
0274 end

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