Home > matpower6.0 > toggle_dcline.m

toggle_dcline

PURPOSE ^

TOGGLE_DCLINE Enable, disable or check status of DC line modeling.

SYNOPSIS ^

function mpc = toggle_dcline(mpc, on_off)

DESCRIPTION ^

TOGGLE_DCLINE Enable, disable or check status of DC line modeling.
   MPC = TOGGLE_DCLINE(MPC, 'on')
   MPC = TOGGLE_DCLINE(MPC, 'off')
   T_F = TOGGLE_DCLINE(MPC, 'status')

   Enables, disables or checks the status of a set of OPF userfcn
   callbacks to implement DC lines as a pair of linked generators.
   While it uses the OPF extension mechanism, this implementation
   works for simple power flow as well as OPF problems.

   These callbacks expect to find a 'dcline' field in the input MPC,
   where MPC.dcline is an ndc x 17 matrix with columns as defined
   in IDX_DCLINE, where ndc is the number of DC lines.

   The 'int2ext' callback also packages up flow results and stores them
   in appropriate columns of MPC.dcline.

   NOTE: Because of the way this extension modifies the number of
   rows in the gen and gencost matrices, caution must be taken
   when using it with other extensions that deal with generators.

   Examples:
       mpc = loadcase('t_case9_dcline');
       mpc = toggle_dcline(mpc, 'on');
       results1 = runpf(mpc);
       results2 = runopf(mpc);

   See also IDX_DCLINE, ADD_USERFCN, REMOVE_USERFCN, RUN_USERFCN.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function mpc = toggle_dcline(mpc, on_off)
0002 %TOGGLE_DCLINE Enable, disable or check status of DC line modeling.
0003 %   MPC = TOGGLE_DCLINE(MPC, 'on')
0004 %   MPC = TOGGLE_DCLINE(MPC, 'off')
0005 %   T_F = TOGGLE_DCLINE(MPC, 'status')
0006 %
0007 %   Enables, disables or checks the status of a set of OPF userfcn
0008 %   callbacks to implement DC lines as a pair of linked generators.
0009 %   While it uses the OPF extension mechanism, this implementation
0010 %   works for simple power flow as well as OPF problems.
0011 %
0012 %   These callbacks expect to find a 'dcline' field in the input MPC,
0013 %   where MPC.dcline is an ndc x 17 matrix with columns as defined
0014 %   in IDX_DCLINE, where ndc is the number of DC lines.
0015 %
0016 %   The 'int2ext' callback also packages up flow results and stores them
0017 %   in appropriate columns of MPC.dcline.
0018 %
0019 %   NOTE: Because of the way this extension modifies the number of
0020 %   rows in the gen and gencost matrices, caution must be taken
0021 %   when using it with other extensions that deal with generators.
0022 %
0023 %   Examples:
0024 %       mpc = loadcase('t_case9_dcline');
0025 %       mpc = toggle_dcline(mpc, 'on');
0026 %       results1 = runpf(mpc);
0027 %       results2 = runopf(mpc);
0028 %
0029 %   See also IDX_DCLINE, ADD_USERFCN, REMOVE_USERFCN, RUN_USERFCN.
0030 
0031 %   MATPOWER
0032 %   Copyright (c) 2011-2016, Power Systems Engineering Research Center (PSERC)
0033 %   by Ray Zimmerman, PSERC Cornell
0034 %
0035 %   This file is part of MATPOWER.
0036 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0037 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0038 
0039 if strcmp(upper(on_off), 'ON')
0040     %% define named indices into data matrices
0041     c = idx_dcline;
0042 
0043     %% check for proper input data
0044     if ~isfield(mpc, 'dcline') || size(mpc.dcline, 2) < c.LOSS1
0045         error('toggle_dcline: case must contain a ''dcline'' field, an ndc x %d matrix.', c.LOSS1);
0046     end
0047     if isfield(mpc, 'dclinecost') && size(mpc.dcline, 1) ~= size(mpc.dclinecost, 1)
0048         error('toggle_dcline: number of rows in ''dcline'' field (%d) and ''dclinecost'' field (%d) do not match.', ...
0049             size(mpc.dcline, 1), size(mpc.dclinecost, 1));
0050     end
0051 %     k = find(mpc.dcline(:, c.LOSS1) < 0);
0052 %     if ~isempty(k)
0053 %         warning('toggle_dcline: linear loss term is negative for DC line from bus %d to %d\n', ...
0054 %             [mpc.dcline(k, c.F_BUS:c.T_BUS)]');
0055 %     end
0056 
0057     %% add callback functions
0058     %% note: assumes all necessary data included in 1st arg (mpc, om, results)
0059     %%       so, no additional explicit args are needed
0060     mpc = add_userfcn(mpc, 'ext2int', @userfcn_dcline_ext2int);
0061     mpc = add_userfcn(mpc, 'formulation', @userfcn_dcline_formulation);
0062     mpc = add_userfcn(mpc, 'int2ext', @userfcn_dcline_int2ext);
0063     mpc = add_userfcn(mpc, 'printpf', @userfcn_dcline_printpf);
0064     mpc = add_userfcn(mpc, 'savecase', @userfcn_dcline_savecase);
0065     mpc.userfcn.status.dcline = 1;
0066 elseif strcmp(upper(on_off), 'OFF')
0067     mpc = remove_userfcn(mpc, 'savecase', @userfcn_dcline_savecase);
0068     mpc = remove_userfcn(mpc, 'printpf', @userfcn_dcline_printpf);
0069     mpc = remove_userfcn(mpc, 'int2ext', @userfcn_dcline_int2ext);
0070     mpc = remove_userfcn(mpc, 'formulation', @userfcn_dcline_formulation);
0071     mpc = remove_userfcn(mpc, 'ext2int', @userfcn_dcline_ext2int);
0072     mpc.userfcn.status.dcline = 0;
0073 elseif strcmp(upper(on_off), 'STATUS')
0074     if isfield(mpc, 'userfcn') && isfield(mpc.userfcn, 'status') && ...
0075             isfield(mpc.userfcn.status, 'dcline')
0076         mpc = mpc.userfcn.status.dcline;
0077     else
0078         mpc = 0;
0079     end
0080 else
0081     error('toggle_dcline: 2nd argument must be ''on'', ''off'' or ''status''');
0082 end
0083 
0084 
0085 %%-----  ext2int  ------------------------------------------------------
0086 function mpc = userfcn_dcline_ext2int(mpc, args)
0087 %
0088 %   mpc = userfcn_dcline_ext2int(mpc, args)
0089 %
0090 %   This is the 'ext2int' stage userfcn callback that prepares the input
0091 %   data for the formulation stage. It expects to find a 'dcline' field
0092 %   in mpc as described above. The optional args are not currently used.
0093 %   It adds two dummy generators for each in-service DC line, with the
0094 %   appropriate upper and lower generation bounds and corresponding
0095 %   entries in gencost. It also expands columns of any A and N matrices
0096 %   accordingly, if present.
0097 
0098 %% define named indices into data matrices
0099 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0100     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0101 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0102     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0103     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0104 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0105 c = idx_dcline;
0106 
0107 %% initialize some things
0108 if isfield(mpc, 'dclinecost')
0109     havecost = 1;
0110 else
0111     havecost = 0;
0112 end
0113 
0114 %% save version with external indexing
0115 mpc.order.ext.dcline = mpc.dcline;              %% external indexing
0116 if havecost
0117     mpc.order.ext.dclinecost = mpc.dclinecost;  %% external indexing
0118 end
0119 
0120 %% work with only in-service DC lines
0121 mpc.order.dcline.status.on  = find(mpc.dcline(:, c.BR_STATUS) >  0);
0122 mpc.order.dcline.status.off = find(mpc.dcline(:, c.BR_STATUS) <= 0);
0123 
0124 %% remove out-of-service DC lines
0125 dc = mpc.dcline(mpc.order.dcline.status.on, :); %% only in-service DC lines
0126 if havecost
0127     dcc = mpc.dclinecost(mpc.order.dcline.status.on, :);    %% only in-service DC lines
0128     mpc.dclinecost = dcc;
0129 end
0130 ndc = size(dc, 1);          %% number of in-service DC lines
0131 o = mpc.order;
0132 
0133 %%-----  convert stuff to internal indexing  -----
0134 dc(:, c.F_BUS) = o.bus.e2i(dc(:, c.F_BUS));
0135 dc(:, c.T_BUS) = o.bus.e2i(dc(:, c.T_BUS));
0136 mpc.dcline = dc;
0137 
0138 %%-----  create gens to represent DC line terminals  -----
0139 %% ensure consistency of initial values of PF, PT and losses
0140 %% (for simple power flow cases)
0141 dc(:, c.PT) = dc(:, c.PF) - (dc(:, c.LOSS0) + dc(:, c.LOSS1) .* dc(:, c.PF));
0142 
0143 %% create gens
0144 fg = zeros(ndc, size(mpc.gen, 2));
0145 fg(:, MBASE)        = 100;
0146 fg(:, GEN_STATUS)   =  dc(:, c.BR_STATUS);  %% status (should be all 1's)
0147 fg(:, PMIN)         = -Inf;
0148 fg(:, PMAX)         =  Inf;
0149 tg = fg;
0150 fg(:, GEN_BUS)      =  dc(:, c.F_BUS);      %% from bus
0151 tg(:, GEN_BUS)      =  dc(:, c.T_BUS);      %% to bus
0152 fg(:, PG)           = -dc(:, c.PF);         %% flow (extracted at "from")
0153 tg(:, PG)           =  dc(:, c.PT);         %% flow (injected at "to")
0154 fg(:, QG)           =  dc(:, c.QF);         %% VAr injection at "from"
0155 tg(:, QG)           =  dc(:, c.QT);         %% VAr injection at "to"
0156 fg(:, VG)           =  dc(:, c.VF);         %% voltage set-point at "from"
0157 tg(:, VG)           =  dc(:, c.VT);         %% voltage set-point at "to"
0158 k = find(dc(:, c.PMIN) >= 0);           %% min positive direction flow
0159 if ~isempty(k)                              %% contrain at "from" end
0160     fg(k, PMAX)     = -dc(k, c.PMIN);       %% "from" extraction lower lim
0161 end
0162 k = find(dc(:, c.PMAX) >= 0);           %% max positive direction flow
0163 if ~isempty(k)                              %% contrain at "from" end
0164     fg(k, PMIN)     = -dc(k, c.PMAX);       %% "from" extraction upper lim
0165 end
0166 k = find(dc(:, c.PMIN) < 0);            %% max negative direction flow
0167 if ~isempty(k)                              %% contrain at "to" end
0168     tg(k, PMIN)     =  dc(k, c.PMIN);       %% "to" injection lower lim
0169 end
0170 k = find(dc(:, c.PMAX) < 0);            %% min negative direction flow
0171 if ~isempty(k)                              %% contrain at "to" end
0172     tg(k, PMAX)     =  dc(k, c.PMAX);       %% "to" injection upper lim
0173 end
0174 fg(:, QMIN)         =  dc(:, c.QMINF);      %% "from" VAr injection lower lim
0175 fg(:, QMAX)         =  dc(:, c.QMAXF);      %% "from" VAr injection upper lim
0176 tg(:, QMIN)         =  dc(:, c.QMINT);      %%  "to"  VAr injection lower lim
0177 tg(:, QMAX)         =  dc(:, c.QMAXT);      %%  "to"  VAr injection upper lim
0178 
0179 %% fudge PMAX a bit if necessary to avoid triggering
0180 %% dispatchable load constant power factor constraints
0181 fg(isload(fg), PMAX) = -1e-6;
0182 tg(isload(tg), PMAX) = -1e-6;
0183 
0184 %% set all terminal buses to PV (except ref bus)
0185 refbus = find(mpc.bus(:, BUS_TYPE) == REF);
0186 mpc.bus(dc(:, c.F_BUS), BUS_TYPE) = PV;
0187 mpc.bus(dc(:, c.T_BUS), BUS_TYPE) = PV;
0188 mpc.bus(refbus, BUS_TYPE) = REF;
0189 
0190 %% expand A and N, if present
0191 nb = size(mpc.bus, 1);
0192 ng = size(mpc.gen, 1);
0193 if isfield(mpc, 'A') && ~isempty(mpc.A)
0194     [mA, nA] = size(mpc.A);
0195     if nA >= 2*nb + 2*ng    %% assume AC dimensions
0196         mpc.A = [   mpc.A(:, 1:2*nb+ng)      sparse(mA, 2*ndc) ...
0197                     mpc.A(:, 2*nb+ng+(1:ng)) sparse(mA, 2*ndc) ...
0198                     mpc.A(:, (2*nb+2*ng+1:nA)) ];
0199     else                    %% assume DC dimensions
0200         mpc.A = [   mpc.A(:, 1:nb+ng)   sparse(mA, 2*ndc) ...
0201                     mpc.A(:, (nb+ng+1:nA)) ];
0202     end
0203 end
0204 if isfield(mpc, 'N') && ~isempty(mpc.N)
0205     [mN, nN] = size(mpc.N);
0206     if nN >= 2*nb + 2*ng    %% assume AC dimensions
0207         mpc.N = [   mpc.N(:, 1:2*nb+ng)      sparse(mN, 2*ndc) ...
0208                     mpc.N(:, 2*nb+ng+(1:ng)) sparse(mN, 2*ndc) ...
0209                     mpc.N(:, (2*nb+2*ng+1:nN)) ];
0210     else                    %% assume DC dimensions
0211         mpc.N = [   mpc.N(:, 1:nb+ng)   sparse(mN, 2*ndc) ...
0212                     mpc.N(:, (nb+ng+1:nN)) ];
0213     end
0214 end
0215 
0216 %% append dummy gens
0217 mpc.gen = [mpc.gen; fg; tg];
0218 
0219 %% gencost
0220 if isfield(mpc, 'gencost') && ~isempty(mpc.gencost)
0221     ngcc = size(mpc.gencost, 2);    %% dimensions of gencost
0222     [pc, qc] = pqcost(mpc.gencost, ng); %% split out re/active costs
0223     if havecost                 %% user has provided costs
0224         ndccc = size(dcc, 2);       %% number of dclinecost columns
0225         ccc = max([ngcc; ndccc]);   %% number of columns in new gencost
0226         if ccc > ngcc               %% right zero-pad gencost
0227             pc = [pc zeros(ng, ccc-ngcc)];
0228             if ~isempty(qc)         %% pad Qg costs, too
0229                 qc = [qc zeros(ng, ccc-ngcc)];
0230             end
0231             ngcc = ccc;
0232         end
0233 
0234         %% flip function across vertical axis and append to gencost
0235         %% (PF for DC line = -PG for dummy gen at "from" bus)
0236         for k = 1:ndc
0237             if dcc(k, MODEL) == POLYNOMIAL
0238                 nc = dcc(k, NCOST);
0239                 temp = dcc(k, NCOST+(1:nc));
0240                 %% flip sign on coefficients of odd terms
0241                 %% (every other starting with linear term,
0242                 %%  that is, the next to last one)
0243                 temp((nc-1):-2:1) = -temp((nc-1):-2:1);
0244             else  %% dcc(k, MODEL) == PW_LINEAR
0245                 nc = dcc(k, NCOST);
0246                 temp = dcc(k, NCOST+(1:2*nc));
0247                 %% switch sign on horizontal coordinate
0248                 xx = -temp(1:2:2*nc);
0249                 yy =  temp(2:2:2*nc);
0250                 temp(1:2:2*nc) = xx(end:-1:1);
0251                 temp(2:2:2*nc) = yy(end:-1:1);
0252             end
0253             padding = zeros(1, ngcc-NCOST-length(temp));
0254             gck = [dcc(k, 1:NCOST) temp padding];
0255             
0256             %% append to gencost
0257             pc = [pc; gck];
0258         end
0259         %% define zero cost for "to" end gen
0260         dcgc = ones(ndc, 1) * [2 0 0 2 zeros(1, ngcc-4)];
0261     else
0262         %% use zero cost as default on "from" end gen
0263         dcgc = ones(ndc, 1) * [2 0 0 2 zeros(1, ngcc-4)];
0264         pc = [pc; dcgc];
0265     end
0266     %% always use zero cost on "to" end gen
0267     pc = [pc; dcgc];
0268 
0269     %% reassemble gencost
0270     if ~isempty(qc)
0271         qc = [qc; dcgc; dcgc];  %% always use zero cost Qg, both ends
0272         mpc.gencost = [pc; qc];
0273     else
0274         mpc.gencost = pc;
0275     end
0276 end
0277 
0278 
0279 %%-----  formulation  --------------------------------------------------
0280 function om = userfcn_dcline_formulation(om, args)
0281 %
0282 %   om = userfcn_dcline_formulation(om, args)
0283 %
0284 %   This is the 'formulation' stage userfcn callback that defines the
0285 %   user constraints for the dummy generators representing DC lines.
0286 %   It expects to find a 'dcline' field in the mpc stored in om, as
0287 %   described above. By the time it is passed to this callback,
0288 %   MPC.dcline should contain only in-service lines and the from and
0289 %   two bus columns should be converted to internal indexing. The
0290 %   optional args are not currently used.
0291 %
0292 %   If Pf, Pt and Ploss are the flow at the "from" end, flow at the
0293 %   "to" end and loss respectively, and L0 and L1 are the linear loss
0294 %   coefficients, the the relationships between them is given by:
0295 %       Pf - Ploss = Pt
0296 %       Ploss = L0 + L1 * Pf
0297 %   If Pgf and Pgt represent the injections of the dummy generators
0298 %   representing the DC line injections into the network, then
0299 %   Pgf = -Pf and Pgt = Pt, and we can combine all of the above to
0300 %   get the following constraint on Pgf ang Pgt:
0301 %       -Pgf - (L0 - L1 * Pgf) = Pgt
0302 %   which can be written:
0303 %       -L0 <= (1 - L1) * Pgf + Pgt <= -L0
0304 
0305 %% define named indices into data matrices
0306 c = idx_dcline;
0307 
0308 %% initialize some things
0309 mpc = get_mpc(om);
0310 dc = mpc.dcline;
0311 ndc = size(dc, 1);              %% number of in-service DC lines
0312 ng  = size(mpc.gen, 1) - 2*ndc; %% number of original gens/disp loads
0313 
0314 %% constraints
0315 nL0 = -dc(:, c.LOSS0) / mpc.baseMVA;
0316 L1  =  dc(:, c.LOSS1);
0317 Adc = [sparse(ndc, ng) spdiags(1-L1, 0, ndc, ndc) speye(ndc, ndc)];
0318 
0319 %% add them to the model
0320 om = add_constraints(om, 'dcline', Adc, nL0, nL0, {'Pg'});
0321 
0322 
0323 %%-----  int2ext  ------------------------------------------------------
0324 function results = userfcn_dcline_int2ext(results, args)
0325 %
0326 %   results = userfcn_dcline_int2ext(results, args)
0327 %
0328 %   This is the 'int2ext' stage userfcn callback that converts everything
0329 %   back to external indexing and packages up the results. It expects to
0330 %   find a 'dcline' field in the results struct as described for mpc
0331 %   above. It also expects that the last 2*ndc entries in the gen and
0332 %   gencost matrices correspond to the in-service DC lines (where ndc is
0333 %   the number of rows in MPC.dcline. These extra rows are removed from
0334 %   gen and gencost and the flow is taken from the PG of these gens and
0335 %   placed in the flow column of the appropiate dcline row. Corresponding
0336 %   columns are also removed from any A and N matrices, if present. The
0337 %   optional args are not currently used.
0338 
0339 %% define named indices into data matrices
0340 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0341     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0342     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0343 c = idx_dcline;
0344 
0345 %% initialize some things
0346 o = results.order;
0347 k = find(o.ext.dcline(:, c.BR_STATUS));
0348 ndc = length(k);                    %% number of in-service DC lines
0349 ng  = size(results.gen, 1) - 2*ndc; %% number of original gens/disp loads
0350 nb  = size(results.bus, 1);
0351 
0352 %% extract dummy gens
0353 fg = results.gen(ng    +(1:ndc), :);
0354 tg = results.gen(ng+ndc+(1:ndc), :);
0355 
0356 %% remove dummy gens
0357 results.gen     = results.gen(1:ng, :);
0358 if isfield(results, 'gencost') && ~isempty(results.gencost)
0359     results.gencost = results.gencost(1:ng, :);
0360 end
0361 
0362 %% delete corresponding columns from A and N, if present
0363 if isfield(results, 'A') && ~isempty(results.A)
0364     [mA, nA] = size(results.A);
0365     if nA >= 2*nb + 2*ng + 4*ndc    %% assume AC dimensions
0366         results.A = results.A(:, [1:2*nb+ng 2*nb+ng+2*ndc+(1:ng) 2*nb+2*ng+4*ndc+1:nA]);
0367     else                            %% assume DC dimensions
0368         results.A = results.A(:, [1:nb+ng nb+ng+2*ndc+1:nA]);
0369     end
0370 end
0371 if isfield(results, 'N') && ~isempty(results.N)
0372     [mN, nN] = size(results.N);
0373     if nN >= 2*nb + 2*ng + 4*ndc    %% assume AC dimensions
0374         results.N = results.N(:, [1:2*nb+ng 2*nb+ng+2*ndc+(1:ng) 2*nb+2*ng+4*ndc+1:nN]);
0375     else                            %% assume DC dimensions
0376         results.N = results.N(:, [1:nb+ng nb+ng+2*ndc+1:nN]);
0377     end
0378 end
0379 
0380 %% get the solved flows
0381 results.dcline(:, c.PF) = -fg(:, PG);
0382 results.dcline(:, c.PT) =  tg(:, PG);
0383 results.dcline(:, c.QF) =  fg(:, QG);
0384 results.dcline(:, c.QT) =  tg(:, QG);
0385 results.dcline(:, c.VF) =  fg(:, VG);
0386 results.dcline(:, c.VT) =  tg(:, VG);
0387 if size(fg, 2) >= MU_QMIN
0388     results.dcline(:, c.MU_PMIN ) = fg(:, MU_PMAX) + tg(:, MU_PMIN);
0389     results.dcline(:, c.MU_PMAX ) = fg(:, MU_PMIN) + tg(:, MU_PMAX);
0390     results.dcline(:, c.MU_QMINF) = fg(:, MU_QMIN);
0391     results.dcline(:, c.MU_QMAXF) = fg(:, MU_QMAX);
0392     results.dcline(:, c.MU_QMINT) = tg(:, MU_QMIN);
0393     results.dcline(:, c.MU_QMAXT) = tg(:, MU_QMAX);
0394 end
0395 
0396 %%-----  convert stuff back to external indexing  -----
0397 results.order.int.dcline = results.dcline;  %% save internal version
0398 %% copy results to external version
0399 o.ext.dcline(k, c.PF:c.VT) = results.dcline(:, c.PF:c.VT);
0400 if size(results.dcline, 2) == c.MU_QMAXT
0401     o.ext.dcline(k, c.MU_PMIN:c.MU_QMAXT) = results.dcline(:, c.MU_PMIN:c.MU_QMAXT);
0402 end
0403 results.dcline = o.ext.dcline;              %% use external version
0404 
0405 
0406 %%-----  printpf  ------------------------------------------------------
0407 function results = userfcn_dcline_printpf(results, fd, mpopt, args)
0408 %
0409 %   results = userfcn_dcline_printpf(results, fd, mpopt, args)
0410 %
0411 %   This is the 'printpf' stage userfcn callback that pretty-prints the
0412 %   results. It expects a results struct, a file descriptor and a MATPOWER
0413 %   options struct. The optional args are not currently used.
0414 
0415 %% define named indices into data matrices
0416 c = idx_dcline;
0417 
0418 %% options
0419 SUPPRESS        = mpopt.out.suppress_detail;
0420 if SUPPRESS == -1
0421     if size(results.bus, 1) > 500
0422         SUPPRESS = 1;
0423     else
0424         SUPPRESS = 0;
0425     end
0426 end
0427 OUT_ALL = mpopt.out.all;
0428 OUT_BRANCH      = OUT_ALL == 1 || (OUT_ALL == -1 && ~SUPPRESS && mpopt.out.branch);
0429 if OUT_ALL == -1
0430     OUT_ALL_LIM = ~SUPPRESS * mpopt.out.lim.all;
0431 elseif OUT_ALL == 1
0432     OUT_ALL_LIM = 2;
0433 else
0434     OUT_ALL_LIM = 0;
0435 end
0436 if OUT_ALL_LIM == -1
0437     OUT_LINE_LIM    = ~SUPPRESS * mpopt.out.lim.line;
0438 else
0439     OUT_LINE_LIM    = OUT_ALL_LIM;
0440 end
0441 ctol = mpopt.opf.violation; %% constraint violation tolerance
0442 ptol = 1e-4;                %% tolerance for displaying shadow prices
0443 
0444 %%-----  print results  -----
0445 dc = results.dcline;
0446 ndc = size(dc, 1);
0447 kk = find(dc(:, c.BR_STATUS) ~= 0);
0448 if OUT_BRANCH
0449     fprintf(fd, '\n================================================================================');
0450     fprintf(fd, '\n|     DC Line Data                                                             |');
0451     fprintf(fd, '\n================================================================================');
0452     fprintf(fd, '\n Line    From     To        Power Flow           Loss     Reactive Inj (MVAr)');
0453     fprintf(fd, '\n   #      Bus     Bus   From (MW)   To (MW)      (MW)       From        To   ');
0454     fprintf(fd, '\n------  ------  ------  ---------  ---------  ---------  ---------  ---------');
0455     loss = 0;
0456     for k = 1:ndc
0457         if dc(k, c.BR_STATUS)   %% status on
0458             fprintf(fd, '\n%5d%8d%8d%11.2f%11.2f%11.2f%11.2f%11.2f', ...
0459                         k, dc(k, c.F_BUS:c.T_BUS), dc(k, c.PF:c.PT), ...
0460                         dc(k, c.PF) - dc(k, c.PT), dc(k, c.QF:c.QT) );
0461             loss = loss + dc(k, c.PF) - dc(k, c.PT);
0462         else
0463             fprintf(fd, '\n%5d%8d%8d%11s%11s%11s%11s%11s', ...
0464                         k, dc(k, c.F_BUS:c.T_BUS), '-  ', '-  ', '-  ', '-  ', '-  ');
0465         end
0466     end
0467     fprintf(fd, '\n                                              ---------');
0468     fprintf(fd, '\n                                     Total:%11.2f\n', loss);
0469 end
0470 
0471 if OUT_LINE_LIM == 2 || (OUT_LINE_LIM == 1 && ...
0472         (any(dc(kk, c.PF) > dc(kk, c.PMAX) - ctol) || ...
0473          any(dc(kk, c.MU_PMIN) > ptol) || ...
0474          any(dc(kk, c.MU_PMAX) > ptol)))
0475     fprintf(fd, '\n================================================================================');
0476     fprintf(fd, '\n|     DC Line Constraints                                                      |');
0477     fprintf(fd, '\n================================================================================');
0478     fprintf(fd, '\n Line    From     To          Minimum        Actual Flow       Maximum');
0479     fprintf(fd, '\n   #      Bus     Bus    Pmin mu     Pmin       (MW)       Pmax      Pmax mu ');
0480     fprintf(fd, '\n------  ------  ------  ---------  ---------  ---------  ---------  ---------');
0481     for k = 1:ndc
0482         if OUT_LINE_LIM == 2 || (OUT_LINE_LIM == 1 && ...
0483                 (dc(k, c.PF) > dc(k, c.PMAX) - ctol || ...
0484                  dc(k, c.MU_PMIN) > ptol || ...
0485                  dc(k, c.MU_PMAX) > ptol))
0486             if dc(k, c.BR_STATUS)   %% status on
0487                 fprintf(fd, '\n%5d%8d%8d', k, dc(k, c.F_BUS:c.T_BUS) );
0488                 if dc(k, c.MU_PMIN) > ptol
0489                     fprintf(fd, '%11.3f', dc(k, c.MU_PMIN) );
0490                 else
0491                     fprintf(fd, '%11s', '-  ' );
0492                 end
0493                 fprintf(fd, '%11.2f%11.2f%11.2f', ...
0494                             dc(k, c.PMIN), dc(k, c.PF), dc(k, c.PMAX) );
0495                 if dc(k, c.MU_PMAX) > ptol
0496                     fprintf(fd, '%11.3f', dc(k, c.MU_PMAX) );
0497                 else
0498                     fprintf(fd, '%11s', '-  ' );
0499                 end
0500             else
0501                 fprintf(fd, '\n%5d%8d%8d%11s%11s%11s%11s%11s', ...
0502                             k, dc(k, c.F_BUS:c.T_BUS), '-  ', '-  ', '-  ', '-  ', '-  ');
0503             end
0504         end
0505     end
0506     fprintf(fd, '\n');
0507 end
0508 
0509 
0510 %%-----  savecase  -----------------------------------------------------
0511 function mpc = userfcn_dcline_savecase(mpc, fd, prefix, args)
0512 %
0513 %   mpc = userfcn_dcline_savecase(mpc, fd, mpopt, args)
0514 %
0515 %   This is the 'savecase' stage userfcn callback that prints the M-file
0516 %   code to save the 'dcline' field in the case file. It expects a
0517 %   MATPOWER case struct (mpc), a file descriptor and variable prefix
0518 %   (usually 'mpc.'). The optional args are not currently used.
0519 
0520 %% define named indices into data matrices
0521 c = idx_dcline;
0522 
0523 %% save it
0524 ncols = size(mpc.dcline, 2);
0525 fprintf(fd, '\n%%%%-----  DC Line Data  -----%%%%\n');
0526 if ncols < c.MU_QMAXT
0527     fprintf(fd, '%%\tfbus\ttbus\tstatus\tPf\tPt\tQf\tQt\tVf\tVt\tPmin\tPmax\tQminF\tQmaxF\tQminT\tQmaxT\tloss0\tloss1\n');
0528 else
0529     fprintf(fd, '%%\tfbus\ttbus\tstatus\tPf\tPt\tQf\tQt\tVf\tVt\tPmin\tPmax\tQminF\tQmaxF\tQminT\tQmaxT\tloss0\tloss1\tmuPmin\tmuPmax\tmuQminF\tmuQmaxF\tmuQminT\tmuQmaxT\n');
0530 end
0531 template = '\t%d\t%d\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%.9g';
0532 if ncols == c.MU_QMAXT
0533     template = [template, '\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f'];
0534 end
0535 template = [template, ';\n'];
0536 fprintf(fd, '%sdcline = [\n', prefix);
0537 fprintf(fd, template, mpc.dcline.');
0538 fprintf(fd, '];\n');
0539 
0540 %% to do, make it save mpc.dclinecost too (somehow I forgot this)
0541 %% have a look at the saving of gencost in savecase for template

Generated on Fri 16-Dec-2016 12:45:37 by m2html © 2005