Home > matpower4.1 > toggle_dcline.m

toggle_dcline

PURPOSE ^

TOGGLE_DCLINE Enable or disable DC line modeling.

SYNOPSIS ^

function mpc = toggle_dcline(mpc, on_off)

DESCRIPTION ^

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

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

Generated on Mon 26-Jan-2015 15:00:13 by m2html © 2005