0001 function [mpc_out, status_out] = syngrid(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
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0054 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0055 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0056 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0057 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0058 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0059 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0060 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0061 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0062
0063
0064 args = varargin;
0065 na = length(args);
0066
0067 if isstruct(args{1}) || ischar(args{1})
0068 mpc = loadcase(args{1});
0069 [~, topo] = sgvm_mpc2data(mpc);
0070 N = length(unique(topo(:)));
0071 elseif isscalar(args{1})
0072 N = args{1};
0073 topo = [];
0074 elseif size(args{1}, 2) == 2
0075 topo = args{1};
0076 N = length(unique(topo(:)));
0077 else
0078 error('syngrid: first argument must be either scalar N, or nl x 2 array TOPO, or MPC struct');
0079 end
0080
0081 if na == 1
0082 sgopt = sg_options();
0083 fname = '';
0084 data = [];
0085 else
0086 if ischar(args{2})
0087 data = sgvm_mpc2data(loadcase(args{2}));
0088 elseif isstruct(args{2})
0089 if isfield(args{2}, 'branch')
0090 data = args{2};
0091 if isfield(data, 'bus')
0092 data = sgvm_mpc2data(data);
0093 end
0094 else
0095 data = [];
0096 sgopt = sg_options(args{2});
0097 end
0098 elseif isempty(args{2})
0099 data = [];
0100 sgopt = sg_options();
0101 else
0102 error('syngrid: argument 2 (SGOPT or DATA) MUST be a structure or empty')
0103 end
0104 if na > 2
0105 if ischar(args{3})
0106 fname = args{3};
0107 if ~exist('sgopt','var')
0108 error('syngrid: when 3rd argument is FNAME, the second argument must be either empty or SGOPT.')
0109 end
0110 elseif isstruct(args{3})
0111 sgopt = sg_options(args{3});
0112 elseif isempty(args{3})
0113 sgopt = sg_options();
0114 else
0115 error('syngrid: 3rd argument is either FNAME or SGOPT structure.')
0116 end
0117 if na > 3
0118 fname = args{4};
0119 if ~ischar(fname)
0120 error('syngrid: FNAME must be a string.')
0121 end
0122 else
0123 if ~exist('fname', 'var')
0124 fname = '';
0125 end
0126 end
0127 else
0128 fname = '';
0129 if ~exist('sgopt', 'var')
0130 sgopt = sg_options();
0131 end
0132 end
0133 end
0134
0135 variations_mode = ~isempty(data);
0136
0137 if N < 25
0138 error('syngrid: minimum allowed for desired number of buses N is 25');
0139 end
0140
0141 if sgopt.verbose
0142 fprintf('SynGrid v%s : creating %d bus synthetic MATPOWER case.\n', sgver, N);
0143 end
0144
0145 if isempty(topo)
0146
0147 [refsys_stat] = sg_refsys_stat(sgopt.bm.refsys);
0148
0149
0150 N0 = 0;
0151 ks = 10;
0152 if N < 150
0153 ks = 0;
0154 elseif N < 300
0155 N0 = 30;
0156 end
0157 topo_pars = {2 2.*sgopt.bm.br2b_ratio};
0158 [N, Zpr, lambda2, L, A, link_ids] = sg_topology(N, N0, ks, 4, ...
0159 topo_pars, {}, refsys_stat.Zpr_pars);
0160 end
0161 if variations_mode
0162 if isempty(topo)
0163 topo = link_ids;
0164 end
0165 seedmpc = sgvm_data2mpc(data, topo, sgopt.vm.smpl);
0166 [mpc, status] = sgvm_mpc_perm(seedmpc, sgopt);
0167 else
0168 [Btypes] = sg_bus_type(link_ids, sgopt.bm.bta_method);
0169 [PgMax] = sg_gen_capacity(link_ids, Btypes, refsys_stat.Tab_2D_Pgmax);
0170 [gencost, genfuel, gentype] = sg_gen_cost(PgMax, sgopt.bm.cost_model, ...
0171 refsys_stat.Tab_2D_gcost);
0172 [PL_setting] = sg_load(link_ids, Btypes, PgMax, sgopt.bm.loading, ...
0173 refsys_stat.Tab_2D_load);
0174 [Pg_setting] = sg_gen_dispatch(PgMax, PL_setting, refsys_stat);
0175 [Line_capacity, Zpr, X, R, ref,link_ids] = sg_flow_lim(link_ids, A, ...
0176 Zpr, PL_setting, Pg_setting, sgopt.bm.br_overload, refsys_stat);
0177
0178
0179 ng = length(PgMax);
0180 nl = length(link_ids);
0181
0182 bus = zeros(N, VMIN);
0183 bus(:, VM) = 1;
0184 bus(:, BUS_I) = (1:N)';
0185 bus(:, BUS_TYPE) = PQ;
0186 bus(PgMax(:,1), BUS_TYPE) = PV;
0187 bus(ref, BUS_TYPE) = REF;
0188 bus(PL_setting(:,1), PD) = PL_setting(:,2);
0189
0190 gen = zeros(ng, APF);
0191 gen(:, [GEN_BUS PG]) = Pg_setting;
0192 gen(:, GEN_STATUS) = Pg_setting(:,2)>0;
0193 gen(:, VG) = 1;
0194 gen(:, PMAX) = PgMax(:,2);
0195
0196 branch = zeros(nl, ANGMAX);
0197 branch(:,[F_BUS T_BUS]) = link_ids;
0198 branch(:, [BR_R BR_X]) = [R,X];
0199 branch(:, RATE_A) = Line_capacity(:,3);
0200 branch(:, BR_STATUS) = 1;
0201
0202
0203 mpc.version = '2';
0204 mpc.baseMVA = 100;
0205 mpc.bus = bus;
0206 mpc.gen = gen;
0207 mpc.branch = branch;
0208 mpc.gencost = gencost;
0209 mpc.genfuel = genfuel;
0210 mpc.gentyp = gentype;
0211 end
0212
0213
0214 if ~isempty(fname)
0215 comment = sprintf('Synthetic %d bus MATPOWER case created by SynGrid\n%% Created by SynGrid v%s, %s', ...
0216 N, sgver, datestr(now, 0));
0217 savecase(fname, comment, mpc);
0218 end
0219
0220
0221 if nargout
0222 mpc_out = mpc;
0223 if nargout > 1
0224 status_out = status;
0225 end
0226 end