Home > matpower7.0 > lib > t > t_opf_softlims.m

t_opf_softlims

PURPOSE ^

T_OPF_SOFTLIMS Tests for userfcn callbacks (softlims) w/OPF.

SYNOPSIS ^

function t_opf_softlims(quiet)

DESCRIPTION ^

T_OPF_SOFTLIMS  Tests for userfcn callbacks (softlims) w/OPF.
   Includes high-level tests of soft limits implementations.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function t_opf_softlims(quiet)
0002 %T_OPF_SOFTLIMS  Tests for userfcn callbacks (softlims) w/OPF.
0003 %   Includes high-level tests of soft limits implementations.
0004 
0005 %   MATPOWER
0006 %   Copyright (c) 2009-2018, Power Systems Engineering Research Center (PSERC)
0007 %   by Ray Zimmerman, PSERC Cornell
0008 %   and Eran Schweitzer, Arizona State University
0009 %
0010 %   This file is part of MATPOWER.
0011 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0012 %   See https://matpower.org for more info.
0013 
0014 if nargin < 1
0015     quiet = 0;
0016 end
0017 
0018 casefile = 'case9';
0019 fname_ac = 'pretty_print_softlims_ac.txt';
0020 fname_dc = 'pretty_print_softlims_dc.txt';
0021 fname = 'pretty_print_softlims';
0022 rn = fix(1e9*rand);
0023 tmp_fname_ac = sprintf('%s_ac_%d.txt', fname, rn);
0024 tmp_fname_dc = sprintf('%s_dc_%d.txt', fname, rn);
0025 
0026 if quiet
0027     verbose = 0;
0028 else
0029     verbose = 0;
0030 end
0031 
0032 t_begin(842, quiet);
0033 
0034 %% define constants
0035 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0036     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0037 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0038     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0039     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0040 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0041     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0042     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0043 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0044 
0045 %% set options
0046 %mpopt = mpoption('opf.dc.solver', 'MIPS', 'opf.ac.solver', 'IPOPT');
0047 mpopt = mpoption('opf.dc.solver', 'MIPS', 'opf.ac.solver', 'MIPS');
0048 %mpopt = mpoption('opf.dc.solver', 'GLPK', 'opf.ac.solver', 'FMINCON');
0049 %mpopt = mpoption('opf.dc.solver', 'GUROBI', 'opf.ac.solver', 'IPOPT');
0050 %mpopt = mpoption('opf.dc.solver', 'CPLEX', 'opf.ac.solver', 'KNITRO');
0051 %mpopt = mpoption(mpopt, 'fmincon.tol_x', 1e-9, 'fmincon.tol_f', 1e-9);
0052 %mpopt = mpoption(mpopt, 'ipopt.opts.tol', 1e-10, 'ipopt.opts.acceptable_tol', 1e-10);
0053 %mpopt = mpoption(mpopt, 'knitro.tol_x', 1e-9, 'knitro.tol_f', 1e-9);
0054 mpopt = mpoption(mpopt, 'opf.violation', 1e-6, 'mips.gradtol', 1e-8, ...
0055         'mips.comptol', 1e-8, 'mips.costtol', 1e-9);
0056 if verbose <= 1
0057     mpopt = mpoption(mpopt, 'out.all', 0);
0058 end
0059 mpopt = mpoption(mpopt, 'verbose', verbose);
0060 
0061 if have_fcn('octave')
0062     sing_matrix_warn_id = 'Octave:singular-matrix';
0063     sing_matrix_warn_id = 'Octave:nearly-singular-matrix';
0064     file_in_path_warn_id = 'Octave:data-file-in-path';
0065     s1 = warning('query', file_in_path_warn_id);
0066     warning('off', file_in_path_warn_id);
0067 else
0068     sing_matrix_warn_id = 'MATLAB:singularMatrix';
0069     sing_matrix_warn_id = 'MATLAB:nearlySingularMatrix';
0070 end
0071 s2 = warning('query', sing_matrix_warn_id);
0072 warning('off', sing_matrix_warn_id);
0073 
0074 %% load and modify case file
0075 mpc = loadcase(casefile);
0076 mpc.bus(:,BUS_I) = 10*mpc.bus(:,BUS_I);
0077 mpc.branch(:,[F_BUS,T_BUS]) = 10*mpc.branch(:,[F_BUS,T_BUS]);
0078 mpc.gen(:,GEN_BUS) = 10*mpc.gen(:,GEN_BUS);
0079 nl = size(mpc.branch, 1);
0080 mpc.gencost(:, NCOST) = 2;
0081 mpc.gencost(:, COST) = [];
0082 mpc.gencost(:, COST) = [50; 40; 25];
0083 mpc.gencost(:, COST+1) = 0;
0084 mpc.branch(2:6, RATE_A) = [0; 120; 0; 120; 0];
0085 mpc.branch(3, RATE_A) = 120;
0086 mpc.branch(5, RATE_A) = 120;
0087 mpc.branch = [mpc.branch(1:4, :); mpc.branch(4, :);  mpc.branch(5:end, :)];
0088 mpc.branch(5, BR_STATUS) = 0;
0089 mpc.branch(:, ANGMIN) = -60;
0090 mpc.branch(:, ANGMAX) = 60;
0091 
0092 nl = size(mpc.branch, 1);   %% number of branches
0093 
0094 %% reorder generators so they are not consecutive
0095 mpc.gen = mpc.gen([3,1,2],:);
0096 mpc.gencost = mpc.gencost([3,1,2],:);
0097 %% duplicate 3rd generator and make it off-line
0098 mpc.gen = [mpc.gen(1,:); mpc.gen(3,:); mpc.gen(2:end,:)];
0099 mpc.gencost = [mpc.gencost(1,:); mpc.gencost(3,:); mpc.gencost(2:end,:)];
0100 mpc.gen(2,GEN_STATUS) = 0;
0101 %% create soft limit inputs (emulates previous implementation just for branches)
0102 mpc.softlims.RATE_A.hl_mod = 'remove';
0103 mpc.softlims.RATE_A.idx  = (2:nl)';
0104 mpc.softlims.RATE_A.cost = 100 * ones(nl-1, 1);
0105 for lim = {'VMIN', 'VMAX', 'ANGMIN', 'ANGMAX', 'PMIN', 'PMAX', 'QMIN', 'QMAX'}
0106     mpc.softlims.(lim{:}).hl_mod = 'none';
0107 end
0108 mpc0 = mpc;     %% save to initialize later runs
0109 
0110 %% mixed softlims structure: uses different types of limits
0111 sdefault = struct();
0112 for lm = {'RATE_A', 'VMIN', 'VMAX', 'ANGMIN', 'ANGMAX', 'PMIN', 'PMAX', ...
0113         'QMIN', 'QMAX'}
0114     lim = lm{:};
0115     switch lim
0116         case 'RATE_A'
0117             sdefault.(lim).hl_mod = 'scale';
0118             sdefault.(lim).hl_val = 1.5;
0119         case 'VMIN'
0120             sdefault.(lim).hl_mod = 'scale';
0121             sdefault.(lim).hl_val = 0.5;
0122         case 'VMAX'
0123             sdefault.(lim).hl_mod = 'scale';
0124             sdefault.(lim).hl_val = 1.5;
0125         case {'PMAX', 'QMAX', 'QMIN'}
0126             sdefault.(lim).hl_mod = 'remove';
0127         case 'PMIN'
0128             sdefault.(lim).hl_mod = 'scale';
0129             sdefault.(lim).hl_val = 0;
0130         case 'ANGMAX'
0131             sdefault.(lim).hl_mod = 'replace';
0132             sdefault.(lim).hl_val = 360;
0133         case 'ANGMIN'
0134             sdefault.(lim).hl_mod = 'replace';
0135             sdefault.(lim).hl_val = -360;
0136     end
0137 end
0138 %% generator ordering
0139 mpc = mpc0;
0140 mpc.bus(:,QD) = mpc.bus(:,QD)*2;
0141 
0142 mpc.gen(:,[QMAX,QMIN]) = [1.1,-1.1; 2.2,-2.2; 3.3,-3.3; 4.4, -4.4];
0143 mpc.gen(:,PMIN) = [1.1; 2.2; 3.3; 4.4];
0144 
0145 % mpc.softlims = sdefault;
0146 mpc.softlims.QMAX = rmfield(mpc.softlims.QMAX, 'hl_mod');
0147 mpc.softlims.QMAX.idx = [1,3];
0148 
0149 t = 'generator ordering: ';
0150 mpc = toggle_softlims(mpc,'on');
0151 r = toggle_run_check(mpc, mpopt, t, 1);
0152 gen_order_check(mpc, r, t, mpopt);
0153 % opf.softlims.default = 0
0154 mpopt.opf.softlims.default = 0;
0155 mpc = mpc0;
0156 mpc = rmfield(mpc,'softlims');
0157 
0158 t = 'mpopt - opf.softlims.default = 0 (all none): ';
0159 mpc = toggle_softlims(mpc,'on');
0160 r = toggle_run_check(mpc, mpopt, t, 1);
0161 for lm = fieldnames(r.softlims).'
0162     lim = lm{:};
0163     t_ok(strcmp(r.softlims.(lim).hl_mod, 'none'), [t lim '.hl_mod = ''none'''])
0164 end
0165 gen_order_check(mpc, r, t, mpopt);
0166 
0167 t = 'mpopt - opf.softlims.default = 0 (w/RATE_A): ';
0168 mpc.softlims.RATE_A = struct('hl_mod', 'scale', 'hl_val', 1.5); %initializing an empty strucure results in default
0169 r = toggle_run_check(mpc, mpopt, t, 1);
0170 vv = r.om.get_idx();
0171 [x0, xmin, xmax] = r.om.params_var();
0172 for lm = fieldnames(r.softlims).'
0173     lim = lm{:};
0174     if ~strcmp(lim, 'RATE_A')
0175         t_ok(strcmp(r.softlims.(lim).hl_mod, 'none'), [t lim '.hl_mod = ''none'''])
0176     else
0177         t_ok(strcmp(r.softlims.RATE_A.hl_mod,'scale'), [t lim '.hl_mod = ''scale'''])
0178         varname = ['s_' lower(lim)];
0179         ub = xmax(vv.i1.(varname):vv.iN.(varname)) * r.baseMVA;
0180         t_is(ub, 0.5*r.branch(r.softlims.RATE_A.idx,RATE_A), 5, [t '.hl_val = 0.5'])
0181     end
0182 end
0183 gen_order_check(mpc, r, t, mpopt);
0184 
0185 mpopt.opf.softlims.default = 1;
0186 mpc = mpc0;
0187 mpc = rmfield(mpc,'softlims');
0188 % mpc.softlims = sdefault;
0189 t = 'AC - opf.softlims.default = 1 (all default): ';
0190 mpc = toggle_softlims(mpc,'on');
0191 r = toggle_run_check(mpc, mpopt, t, 1);
0192 vv = r.om.get_idx();
0193 [x0, xmin, xmax] = r.om.params_var();
0194 for lm = fieldnames(r.softlims).'
0195     lim = lm{:};
0196     varname = ['s_' lower(lim)];
0197     ub = xmax(vv.i1.(varname):vv.iN.(varname));
0198     switch lim
0199         case {'RATE_A', 'PMAX', 'PMIN', 'QMAX', 'QMIN'}
0200             ub = ub * r.baseMVA;
0201         case {'ANGMAX', 'ANGMIN'}
0202             ub = ub * 180/pi;
0203     end
0204     switch lim
0205         case {'PMAX', 'QMAX', 'RATE_A', 'ANGMAX', 'VMAX'}
0206             %% default hl_mod = 'remove'
0207             t_ok(strcmp(r.softlims.(lim).hl_mod,'remove'), [t lim '.hl_mod = ''remove'''])
0208             t_ok(r.softlims.(lim).hl_val == Inf, [t lim '.hl_val = Inf'])
0209             t_ok(all(isinf(ub)), [t lim ' ub = Inf'])
0210         case {'QMIN', 'ANGMIN'}
0211             %% default hl_mod = 'remove'
0212             t_ok(strcmp(r.softlims.(lim).hl_mod,'remove'), [t lim '.hl_mod = ''remove'''])
0213             t_ok(r.softlims.(lim).hl_val == -Inf, [t lim '.hl_val = -Inf'])
0214             t_ok(all(isinf(ub)), [t lim ' ub = Inf'])
0215         case 'VMIN'
0216             %% default hl_mod = 'replace'
0217             t_ok(strcmp(r.softlims.(lim).hl_mod,'replace'), [t lim '.hl_mod = ''replace'''])
0218             t_ok(r.softlims.(lim).hl_val == 0, [t lim '.hl_val = 0'])
0219             t_ok(all(ub == r.bus(:,VMIN)), [t lim ' ub = VMIN'])
0220         case 'PMIN'
0221             %% default hl_mod = 'replace'
0222             t_ok(strcmp(r.softlims.(lim).hl_mod,'replace'), [t lim '.hl_mod = ''replace'''])
0223             t_ok(all(r.softlims.(lim).hl_val(r.gen(r.softlims.PMIN.idx, PMIN) > 0) == 0), [t lim '.hl_val = 0 (gens)'])
0224             t_ok(all(ub(r.gen(r.softlims.PMIN.idx, PMIN) > 0) == r.gen(r.softlims.PMIN.idx,PMIN)), [t lim ' ub=PMIN (gens)'])
0225     end
0226 end
0227 gen_order_check(mpc, r, t, mpopt);
0228 
0229 t = 'DC - opf.softlims.default = 1 (all default): ';
0230 mpopt1 = mpoption(mpopt, 'model', 'DC');
0231 r = toggle_run_check(mpc, mpopt1, t, 1);
0232 vv = r.om.get_idx();
0233 [x0, xmin, xmax] = r.om.params_var();
0234 for lm = fieldnames(r.softlims).'
0235     lim = lm{:};
0236     varname = ['s_' lower(lim)];
0237     ub = xmax(vv.i1.(varname):vv.iN.(varname));
0238     switch lim
0239         case {'RATE_A', 'PMAX', 'PMIN', 'QMAX', 'QMIN'}
0240             ub = ub * r.baseMVA;
0241         case {'ANGMAX', 'ANGMIN'}
0242             ub = ub * 180/pi;
0243     end
0244     switch lim
0245         case {'PMAX', 'QMAX', 'RATE_A', 'ANGMAX', 'VMAX'}
0246             %% default hl_mod = 'remove'
0247             t_ok(strcmp(r.softlims.(lim).hl_mod,'remove'), [t lim '.hl_mod = ''remove'''])
0248             t_ok(r.softlims.(lim).hl_val == Inf, [t lim '.hl_val = Inf'])
0249             t_ok(all(isinf(ub)), [t lim ' ub = Inf'])
0250         case {'QMIN', 'ANGMIN'}
0251             %% default hl_mod = 'remove'
0252             t_ok(strcmp(r.softlims.(lim).hl_mod,'remove'), [t lim '.hl_mod = ''remove'''])
0253             t_ok(r.softlims.(lim).hl_val == -Inf, [t lim '.hl_val = -Inf'])
0254             t_ok(all(isinf(ub)), [t lim ' ub = Inf'])
0255         case 'VMIN'
0256             %% default hl_mod = 'replace'
0257             t_ok(strcmp(r.softlims.(lim).hl_mod,'replace'), [t lim '.hl_mod = ''replace'''])
0258             t_ok(r.softlims.(lim).hl_val == 0, [t lim '.hl_val = 0'])
0259             t_ok(all(ub == r.bus(:,VMIN)), [t lim ' ub = VMIN'])
0260         case 'PMIN'
0261             %% default hl_mod = 'replace'
0262             t_ok(strcmp(r.softlims.(lim).hl_mod,'replace'), [t lim '.hl_mod = ''replace'''])
0263             t_ok(all(r.softlims.(lim).hl_val(r.gen(r.softlims.PMIN.idx, PMIN) > 0) == 0), [t lim '.hl_val = 0 (gens)'])
0264             t_ok(all(ub(r.gen(r.softlims.PMIN.idx, PMIN) > 0) == r.gen(r.softlims.PMIN.idx,PMIN)), [t lim ' ub=PMIN (gens)'])
0265     end
0266 end
0267 gen_order_check(mpc, r, t, mpopt1);
0268 
0269 %% Default settings check
0270 mpc = mpc0;
0271 mpc.softlims = sdefault;
0272 
0273 t = 'Defaults - no active softlims: ';
0274 r = toggle_run_check(mpc, mpopt, t, 0);
0275 delta = calc_branch_angle(r);
0276 overload_loop(r, t, 0);
0277 t_is(r.bus(:,VM), [1.040963;1.1;1.1;1.042513;1.041787;1.096141;1.079794;1.089516;1.031234], 4, [t 'Vm']);
0278 t_is(r.branch(:,PF), [17.3121  -25.0634 -115.1668  239.9012         0  119.9646   18.5301  -66.4562   84.9411  -42.2020].', 4, [t 'PF'])
0279 t_is(r.branch(:,QF), [-2.7212   -2.8421  -16.2418   21.2760         0   -2.9141  -25.3254  -17.1234    8.9449  -17.4049].', 4, [t 'QF'])
0280 t_is(r.branch(:,PT), [-17.3121   25.1668  119.9366 -239.9012         0 -118.5301  -18.4848   66.4562  -82.7980   42.3756].',4, [t 'PT'])
0281 t_is(r.branch(:,QT), [2.8844  -13.7582   -3.9017    6.8158         0   -9.6746    8.1785   19.6031  -32.5951   -0.0423].', 4, [t 'QT'])
0282 t_is(delta, [0.5265   -1.2681   -9.9352    6.6955         0    5.8081    0.7187   -1.9861    6.5458   -1.8692].', 4, [t 'delta'])
0283 t_is(r.gen(:,PG), [239.9012         0   17.3121   66.4562].', 4, [t 'PG'])
0284 t_is(r.gen(:,QG), [21.2760         0   -2.7212   19.6031].', 4, [t 'QG'])
0285 t_is(r.bus(:,MU_VMAX), [0;526.455671;232.322240;0;0;0;0;0;0], 4, [t 'mu VM ub'])
0286 t_is(r.bus(:,MU_VMIN), zeros(9,1), 4, [t 'mu VM lb'])
0287 t_is(sum(r.branch(:,MU_SF:MU_ST),2), [0.0000         0   29.2428         0         0    8.5610         0    0.0000    0.0000    0.0000].', 4, [t 'mu SF+ST'])
0288 t_is(r.branch(:,MU_ANGMAX), zeros(10,1), 4, [t 'mu ANGMAX'])
0289 t_is(r.branch(:,MU_ANGMIN), zeros(10,1), 4, [t 'mu ANGMIN'])
0290 t_is(r.gen(:,MU_PMAX), zeros(4,1), 4, [t 'mu PMAX'])
0291 t_is(r.gen(:,MU_PMIN), zeros(4,1), 4, [t 'mu PMIN'])
0292 t_is(r.gen(:,MU_QMAX), zeros(4,1), 4, [t 'mu QMAX'])
0293 t_is(r.gen(:,MU_QMIN), zeros(4,1), 4, [t 'mu QMIN'])
0294 gen_order_check(mpc, r, t, mpopt);
0295 
0296 t = 'Defaults - softlims on: ';
0297 mpc = toggle_softlims(mpc,'on');
0298 r = toggle_run_check(mpc, mpopt, t, 1);
0299 delta = calc_branch_angle(r);
0300 overload_loop(r, t, 1);
0301 t_is(r.bus(:,VM), [1.040963;1.1;1.1;1.042513;1.041787;1.096141;1.079794;1.089516;1.031234], 4, [t 'Vm']);
0302 t_is(r.branch(:,PF), [17.3121  -25.0634 -115.1668  239.9012         0  119.9646   18.5301  -66.4562   84.9411  -42.2020].', 4, [t 'PF'])
0303 t_is(r.branch(:,QF), [-2.7212   -2.8421  -16.2418   21.2760         0   -2.9141  -25.3254  -17.1234    8.9449  -17.4049].', 4, [t 'QF'])
0304 t_is(r.branch(:,PT), [-17.3121   25.1668  119.9366 -239.9012         0 -118.5301  -18.4848   66.4562  -82.7980   42.3756].',4, [t 'PT'])
0305 t_is(r.branch(:,QT), [2.8844  -13.7582   -3.9017    6.8158         0   -9.6746    8.1785   19.6031  -32.5951   -0.0423].', 4, [t 'QT'])
0306 t_is(delta, [0.5265   -1.2681   -9.9352    6.6955         0    5.8081    0.7187   -1.9861    6.5458   -1.8692].', 4, [t 'delta'])
0307 t_is(r.gen(:,PG), [239.9012         0   17.3121   66.4562].', 4, [t 'PG'])
0308 t_is(r.gen(:,QG), [21.2760         0   -2.7212   19.6031].', 4, [t 'QG'])
0309 t_is(r.bus(:,MU_VMAX), [0;526.455671;232.322240;0;0;0;0;0;0], 4, [t 'mu VM ub'])
0310 t_is(r.bus(:,MU_VMIN), zeros(9,1), 4, [t 'mu VM lb'])
0311 t_is(sum(r.branch(:,MU_SF:MU_ST),2), [0.0000         0   29.2428         0         0    8.5610         0    0.0000    0.0000    0.0000].', 4, [t 'mu SF+ST'])
0312 t_is(r.branch(:,MU_ANGMAX), zeros(10,1), 4, [t 'mu ANGMAX'])
0313 t_is(r.branch(:,MU_ANGMIN), zeros(10,1), 4, [t 'mu ANGMIN'])
0314 t_is(r.gen(:,MU_PMAX), zeros(4,1), 4, [t 'mu PMAX'])
0315 t_is(r.gen(:,MU_PMIN), zeros(4,1), 4, [t 'mu PMIN'])
0316 t_is(r.gen(:,MU_QMAX), zeros(4,1), 4, [t 'mu QMAX'])
0317 t_is(r.gen(:,MU_QMIN), zeros(4,1), 4, [t 'mu QMIN'])
0318 gen_order_check(mpc, r, t, mpopt);
0319 
0320 %% tighten limits to get violations
0321 t = 'Defaults - softlims w/overloads: ';
0322 mpc = mpc0;
0323 mpc.softlims = sdefault;
0324 mpc.bus(4,VMAX) = 0.9;
0325 mpc.softlims.VMAX.cost = 75000;
0326 mpc.bus(9,VMIN)  = 1.05;
0327 mpc.softlims.VMIN.cost = 75000;
0328 mpc.softlims.VMIN.busnum = 10*[1 2 8 9]';
0329 mpc.softlims.RATE_A.cost = 10;
0330 mpc.gen(3,PMIN) = 25; 
0331 mpc.softlims.PMIN.cost = 5;
0332 mpc.gen(1,PMAX) = 225; 
0333 mpc.softlims.PMAX.idx  = [1;2;3;4];
0334 mpc.softlims.PMAX.cost = [3;1000;1000;1000];
0335 mpc.gen(4,QMAX) = 50; 
0336 mpc.softlims.QMAX.idx  = [1;2;3;4];
0337 mpc.softlims.QMAX.cost = [1000;1000;1000;20];
0338 mpc.gen(3,QMIN) = -45; 
0339 mpc.softlims.QMIN.idx  = [1;2;3;4];
0340 mpc.softlims.QMIN.cost = [1000; 1000; 10; 1000];
0341 mpc.branch(3,ANGMIN) = -5;
0342 mpc.branch(4,ANGMAX) = +5;
0343 mpc.softlims.ANGMIN.idx = (1:nl).';
0344 mpc.softlims.ANGMAX.idx = (1:nl).';
0345 mpc.softlims.ANGMIN.cost = 1e3*ones(10,1);
0346 mpc.softlims.ANGMAX.cost = 1e3*ones(10,1);
0347 mpc.softlims.ANGMIN.cost(3) = 20;
0348 mpc.softlims.ANGMAX.cost(4) = 20;
0349 mpc = toggle_softlims(mpc,'on');
0350 r = toggle_run_check(mpc, mpopt, t, 1);
0351 overload_loop(r, t, 1);
0352 mu_cost_test(r, t, mpopt);
0353 gen_order_check(mpc, r, t, mpopt);
0354 
0355 t = 'printpf - AC';
0356 [fd, msg] = fopen(tmp_fname_ac, 'at');
0357 if fd == -1
0358     error(msg);
0359 else
0360     mpopt2 = mpoption(mpopt, 'out.all', -1, 'out.bus', 0, 'out.branch', 0, 'out.sys_sum', 0);
0361     printpf(r, fd, mpopt2);
0362     fclose(fd);
0363 end
0364 got = fileread(tmp_fname_ac);
0365 got = strrep(got, char([13 10]), char(10));             %% Win to Unix EOL chars
0366 got = regexprep(got, 'Converged in (.*) seconds', 'Converged in 0.00 seconds');
0367 expected = fileread(fname_ac);
0368 expected = strrep(expected, char([13 10]), char(10));   %% Win to Unix EOL chars
0369 t_ok(strcmp(got, expected), t);
0370 delete(tmp_fname_ac);
0371 
0372 t = 'Repeat solve: ';
0373 r2 = runopf(r, mpopt);
0374 t_is(r2.bus, r.bus, 4, [t 'bus matrices are the same'])
0375 t_is(r2.branch, r.branch, 4, [t 'branch matrices are the same'])
0376 t_is(r2.gen, r.gen, 4, [t 'bus matrices are the same'])
0377 
0378 %% test save case
0379 t = 'savecase(fname, r) : ';
0380 fn = sprintf('softlims_savecase_test_%d', fix(1e8*rand));
0381 savecase(fn, r);
0382 mpc1 = loadcase(fn);
0383 delete([fn '.m']);
0384 t_ok(isfield(mpc1, 'softlims'), [t 'mpc.softlims']);
0385 for lm = fieldnames(r.softlims).'
0386     lim = lm{:};
0387     t_ok(isfield(mpc1.softlims, lim), [t 'mpc.softlims.' lim])
0388     for f = fieldnames(r.softlims.(lim)).'
0389         field = f{:};
0390         if any(isinf(r.softlims.(lim).(field)))
0391             t_ok(isequal(mpc1.softlims.(lim).(field), r.softlims.(lim).(field)), [t 'mpc.softlims.' lim '.' field])
0392         else
0393             t_is(mpc1.softlims.(lim).(field), r.softlims.(lim).(field), 5, [t 'mpc.softlims.' lim '.' field])
0394         end
0395     end
0396 end
0397 
0398 %% defaults with DC
0399 mpc = mpc0;
0400 mpc.softlims = sdefault;
0401 t = 'DC - hard limits : ';
0402 t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
0403 mpopt1 = mpoption(mpopt, 'model', 'DC');
0404 r = rundcopf(mpc, mpopt1);
0405 t_ok(r.success, [t 'success']);
0406 delta = calc_branch_angle(r);
0407 overload_loop(r, t, 0, {}, 1);
0408 t_is(r.gen(:, PG), [240.0000         0   12.6870   62.3130].', 4, [t 'Pg']);
0409 t_is(r.branch(:, PF), [12.687; -30; -120; 240; 0; 120; 20; -62.3130; 82.3130; -42.687], 4, [t 'Pf']);
0410 t_is(delta, [0.4187   -1.5814  -11.6883    8.0581         0    6.9305    0.8251   -2.2314    7.5931   -2.0789].', 4, [t 'delta'])
0411 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 35.6504; 0; 0; 7.9756; 0; 0; 0; 0], 4, [t 'mu Pf']);
0412 gen_order_check(mpc, r, t, mpopt1);
0413 
0414 t = 'DC - softlims on: ';
0415 mpc = toggle_softlims(mpc,'on');
0416 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0417 r = rundcopf(mpc, mpopt1);
0418 t_ok(r.success, [t 'success']);
0419 delta = calc_branch_angle(r);
0420 overload_loop(r, t, 1, {}, 1);
0421 t_is(r.gen(:, PG), [240.0000         0   12.6870   62.3130].', 4, [t 'Pg']);
0422 t_is(r.branch(:, PF), [12.687; -30; -120; 240; 0; 120; 20; -62.3130; 82.3130; -42.687], 4, [t 'Pf']);
0423 t_is(delta, [0.4187   -1.5814  -11.6883    8.0581         0    6.9305    0.8251   -2.2314    7.5931   -2.0789].', 4, [t 'delta'])
0424 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 35.6504; 0; 0; 7.9756; 0; 0; 0; 0], 4, [t 'mu Pf']);
0425 gen_order_check(mpc, r, t, mpopt1);
0426 
0427 t = 'DC - regression : ';
0428 mpc = mpc0;
0429 mpc = toggle_softlims(mpc,'on');
0430 t_ok(toggle_softlims(mpc, 'status'), [t 'toggle_softlims(mpc, ''status'') == 1']);
0431 mpc.softlims = struct();
0432 mpc.softlims.RATE_A.hl_mod = 'none';
0433 r = rundcopf(mpc, mpopt1);
0434 t_ok(r.success, [t 'success']);
0435 
0436 %% tighten limits to get violations
0437 t = 'DC - softlims with overloads: ';
0438 mpc = mpc0;
0439 mpc.softlims = sdefault;
0440 mpc.branch([3,6,7,8],RATE_A) = 75;
0441 mpc.softlims.RATE_A.cost = 15;
0442 mpc.gen(3,PMIN) = 75; 
0443 mpc.gen(4,PMIN) = 80;
0444 mpc.softlims.PMIN.idx = [1;2;3;4];
0445 mpc.softlims.PMIN.cost = [1000;1000;5;4];
0446 mpc.gen(1,PMAX) = 90; 
0447 mpc.softlims.PMAX.idx = [1;2;3;4];
0448 mpc.softlims.PMAX.cost = [10;1000;1000;1000];
0449 mpc.branch(3,ANGMIN) = -5;
0450 mpc.softlims.ANGMIN.idx = (1:10)';
0451 mpc.softlims.ANGMIN.cost = 1000*ones(10,1);
0452 mpc.softlims.ANGMIN.cost(3) = 5;
0453 mpc.branch(9,ANGMAX) = +5;
0454 mpc.softlims.ANGMAX.idx = (1:10)';
0455 mpc.softlims.ANGMAX.cost = 1000*ones(10,1);
0456 mpc.softlims.ANGMAX.cost(9) = 5;
0457 mpc = toggle_softlims(mpc,'on');
0458 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0459 r = rundcopf(mpc, mpopt1);
0460 t_ok(r.success, [t 'success']);
0461 overload_loop(r, t, 1, {}, 1);
0462 mu_cost_test(r, t, mpopt1);
0463 gen_order_check(mpc, r, t, mpopt1);
0464 
0465 t = 'printpf - DC';
0466 [fd, msg] = fopen(tmp_fname_dc, 'at');
0467 if fd == -1
0468     error(msg);
0469 else
0470     mpopt2 = mpoption(mpopt1, 'out.all', -1, 'out.bus', 0, 'out.branch', 0, 'out.sys_sum', 0);
0471     printpf(r, fd, mpopt2);
0472     fclose(fd);
0473 end
0474 got = fileread(tmp_fname_dc);
0475 got = strrep(got, char([13 10]), char(10));             %% Win to Unix EOL chars
0476 got = regexprep(got, 'Converged in (.*) seconds', 'Converged in 0.00 seconds');
0477 expected = fileread(fname_dc);
0478 expected = strrep(expected, char([13 10]), char(10));   %% Win to Unix EOL chars
0479 t_ok(strcmp(got, expected), t);
0480 delete(tmp_fname_dc);
0481 
0482 %% unbounded limits
0483 mpc = mpc0;
0484 mpc.softlims.RATE_A.hl_mod = 'none';
0485 mpc.softlims.VMAX.hl_mod   = 'remove';
0486 mpc.softlims.VMIN.hl_mod   = 'remove';
0487 t = 'V lims - hard limits: ';
0488 t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
0489 r = runopf(mpc, mpopt);
0490 t_ok(r.success, [t 'success']);
0491 overload_loop(r, t, 0);
0492 t_is(r.bus(:,VM), [1.040963;1.1;1.1;1.042513;1.041787;1.096141;1.079794;1.089516;1.031234], 4, [t 'Vm']);
0493 t_is(r.bus(:,MU_VMAX), [0;526.455671;232.322240;0;0;0;0;0;0], 4, [t 'mu VM ub'])
0494 gen_order_check(mpc, r, t, mpopt);
0495 
0496 mpc = toggle_softlims(mpc,'on');
0497 t = 'V lims (remove) - softlims (satisfied): ';
0498 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0499 r = runopf(mpc, mpopt);
0500 t_ok(r.success, [t 'success']);
0501 t_is(r.bus(:,VM), [1.040963;1.1;1.1;1.042513;1.041787;1.096141;1.079794;1.089516;1.031234], 4, [t 'Vm']);
0502 t_is(r.bus(:,MU_VMAX), [0;526.455671;232.322240;0;0;0;0;0;0], 4, [t 'mu VM ub'])
0503 gen_order_check(mpc, r, t, mpopt);
0504 
0505 mpc.bus(4:9, [VMIN, VMAX]) = 1;
0506 t = 'V lims (remove) - softlims w/overloads: ';
0507 r = toggle_run_check(mpc, mpopt, t, 1);
0508 overload_loop(r, t, 1, {'VMIN', 'VMAX'})
0509 overload_loop(r, t, 0, {'VMIN', 'VMAX'})
0510 mu_cost_test(r, t, mpopt);
0511 gen_order_check(mpc, r, t, mpopt);
0512 
0513 %% scale modification
0514 mpc = mpc0;
0515 mpc.softlims = sdefault;
0516 for lm = fieldnames(mpc.softlims).'
0517     lim = lm{:};
0518     if ~ismember(lim,{'VMIN','VMAX'})
0519         mpc.softlims.(lim).hl_mod = 'none';
0520     end
0521 end
0522 mpc.bus(4:9, [VMIN, VMAX]) = 1;
0523 mpc = toggle_softlims(mpc,'on');
0524 t = 'V lims (scale) - softlims w/overloads: ';
0525 r = toggle_run_check(mpc, mpopt, t, 1);
0526 overload_loop(r, t, 1, {'VMIN', 'VMAX'})
0527 overload_loop(r, t, 0, {'VMIN', 'VMAX'})
0528 mu_cost_test(r, t, mpopt);
0529 gen_order_check(mpc, r, t, mpopt);
0530 
0531 %% replace modification
0532 mpc = mpc0;
0533 mpc.softlims = sdefault;
0534 for lm = fieldnames(mpc.softlims).'
0535     lim = lm{:};
0536     if strcmp(lim,'VMIN')
0537         mpc.softlims.VMIN.hl_mod = 'replace';
0538         mpc.softlims.VMIN.hl_val   = 0.7;
0539     elseif strcmp(lim,'VMAX')
0540         mpc.softlims.VMAX.hl_mod = 'replace';
0541         mpc.softlims.VMAX.hl_val   = 1.2;
0542     else
0543         mpc.softlims.(lim).hl_mod = 'none';
0544     end
0545 end
0546 mpc.bus(4:9, [VMIN, VMAX]) = 1;
0547 mpc = toggle_softlims(mpc,'on');
0548 t = 'V lims (replace) - softlims w/overloads: ';
0549 r = toggle_run_check(mpc, mpopt, t, 1);
0550 overload_loop(r, t, 1, {'VMIN', 'VMAX'})
0551 overload_loop(r, t, 0, {'VMIN', 'VMAX'})
0552 vv = r.om.get_idx();
0553 [x0, xmin, xmax] = r.om.params_var();
0554 ub = xmax(vv.i1.s_vmin:vv.iN.s_vmin);
0555 t_ok(all(ub == (r.bus(r.softlims.VMIN.idx,VMIN) - 0.7)), [t 'VMIN ub = VMIN - 0.7'])
0556 ub = xmax(vv.i1.s_vmax:vv.iN.s_vmax);
0557 t_ok(all(ub == (1.2 - r.bus(r.softlims.VMAX.idx,VMAX))), [t 'VMIN ub = 1.2 - VMAX'])
0558 mu_cost_test(r, t, mpopt);
0559 gen_order_check(mpc, r, t, mpopt);
0560 
0561 %% shift modification
0562 mpc = mpc0;
0563 mpc.softlims = sdefault;
0564 for lm = fieldnames(mpc.softlims).'
0565     lim = lm{:};
0566     if strcmp(lim,'VMIN')
0567         mpc.softlims.VMIN.hl_mod = 'shift';
0568         mpc.softlims.VMIN.hl_val   = 0.2;
0569     elseif strcmp(lim,'VMAX')
0570         mpc.softlims.VMAX.hl_mod = 'shift';
0571         mpc.softlims.VMAX.hl_val   = 0.2;
0572     else
0573         mpc.softlims.(lim).hl_mod = 'none';
0574     end
0575 end
0576 mpc.bus(4:9, [VMIN, VMAX]) = 1;
0577 mpc = toggle_softlims(mpc,'on');
0578 t = 'V lims (shift) - softlims w/overloads: ';
0579 r = toggle_run_check(mpc, mpopt, t, 1);
0580 overload_loop(r, t, 1, {'VMIN', 'VMAX'})
0581 overload_loop(r, t, 0, {'VMIN', 'VMAX'})
0582 vv = r.om.get_idx();
0583 [x0, xmin, xmax] = r.om.params_var();
0584 ub = xmax(vv.i1.s_vmin:vv.iN.s_vmin);
0585 t_ok(all(ub == 0.2), [t 'VMIN ub = shift (0.2)'])
0586 ub = xmax(vv.i1.s_vmax:vv.iN.s_vmax);
0587 t_ok(all(ub == 0.2), [t 'VMAX ub = shift (0.2)'])
0588 mu_cost_test(r, t, mpopt);
0589 gen_order_check(mpc, r, t, mpopt);
0590 %% Tests
0591 %% the following are all the test from the original softlims implementation
0592 %% that only included RATE_A. The only changes are adaptations to the
0593 %% changed data structure.
0594 mpc = mpc0;
0595 t = 'DC - hard limits : ';
0596 t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
0597 mpopt1 = mpoption(mpopt, 'model', 'DC');
0598 r = rundcopf(mpc, mpopt1);
0599 t_ok(r.success, [t 'success']);
0600 t_ok(~isfield(r.softlims.RATE_A, 'overload'), [t 'no softlims.RATE_A.overload']);
0601 t_ok(~isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'no softlims.RATE_A.ovl_cost']);
0602 t_is(r.f, 9126.87, 4, [t 'f']);
0603 t_is(r.gen(:, PG), [240.0000         0   12.6870   62.3130].', 4, [t 'Pg']);
0604 t_is(r.branch(:, PF), [12.687; -30; -120; 240; 0; 120; 20; -62.3130; 82.3130; -42.687], 4, [t 'Pf']);
0605 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 35.6504; 0; 0; 7.9756; 0; 0; 0; 0], 4, [t 'mu Pf']);
0606 gen_order_check(mpc, r, t, mpopt1);
0607 
0608 t = 'DC - softlims (satisfied) : ';
0609 mpc = toggle_softlims(mpc, 'on');
0610 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0611 r = rundcopf(mpc, mpopt1);
0612 t_ok(r.success, [t 'success']);
0613 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0614 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0615 t_is(r.f, 9126.87, 4, [t 'f']);
0616 t_is(r.gen(:, PG), [240.0000         0   12.6870   62.3130].', 4, [t 'Pg']);
0617 t_is(r.branch(:, PF), [12.687; -30; -120; 240; 0; 120; 20; -62.3130; 82.3130; -42.687], 4, [t 'Pf']);
0618 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 35.6504; 0; 0; 7.9756; 0; 0; 0; 0], 4, [t 'mu Pf']);
0619 t_is(r.softlims.RATE_A.overload, zeros(10, 1), 12, [t 'softlims.overload']);
0620 t_is(r.softlims.RATE_A.ovl_cost, zeros(10, 1), 12, [t 'softlims.ovl_cost']);
0621 t_is(r.order.branch.status.on(r.order.int.softlims.RATE_A.idx), [3; 6; 8; 9; 10], 12, [t 'mu Pf']);
0622 gen_order_check(mpc, r, t, mpopt1);
0623 
0624 t = 'savecase(fname, mpc) : ';
0625 fn = sprintf('softlims_savecase_test_%d', fix(1e8*rand));
0626 savecase(fn, mpc);
0627 mpc1 = loadcase(fn);
0628 delete([fn '.m']);
0629 t_ok(isfield(mpc1, 'softlims'), [t 'mpc.softlims']);
0630 for lm = fieldnames(mpc.softlims).'
0631     lim = lm{:};
0632     t_ok(isfield(mpc1.softlims, lim), [t 'mpc.softlims.' lim])
0633     for f = fieldnames(mpc.softlims.(lim)).'
0634         field = f{:};
0635         if any(isinf(mpc.softlims.(lim).(field)))
0636             t_ok(isequal(mpc1.softlims.(lim).(field), mpc.softlims.(lim).(field)), [t 'mpc.softlims.' lim '.' field])
0637         else
0638             t_is(mpc1.softlims.(lim).(field), mpc.softlims.(lim).(field), 5, [t 'mpc.softlims.' lim '.' field])
0639         end
0640     end
0641 end
0642 
0643 t = 'savecase(fname, results)+gentype/fuel: ';
0644 r.genfuel = {'hydro'; 'coal'; 'ng'; 'coal'};
0645 r.gentype = {'HY'; 'ST'; 'GT'; 'ST'};
0646 fn = sprintf('softlims_savecase_test_%d', fix(1e8*rand));
0647 savecase(fn, r);
0648 mpc1 = loadcase(fn);
0649 delete([fn '.m']);
0650 t_ok(isfield(mpc1, 'softlims'), [t 'results.softlims']);
0651 for lm = fieldnames(r.softlims).'
0652     lim = lm{:};
0653     t_ok(isfield(mpc1.softlims, lim), [t 'results.softlims.' lim])
0654     for f = fieldnames(r.softlims.(lim)).'
0655         field = f{:};
0656         if any(isinf(r.softlims.(lim).(field)))
0657             t_ok(isequal(mpc1.softlims.(lim).(field), r.softlims.(lim).(field)), [t 'results.softlims.' lim '.' field])
0658         else
0659             t_is(mpc1.softlims.(lim).(field), r.softlims.(lim).(field), 5, [t 'results.softlims.' lim '.' field])
0660         end
0661     end
0662 end
0663 t_ok(isfield(mpc1, 'gentype'), [t 'results.gentype']);
0664 t_ok(isfield(mpc1, 'genfuel'), [t 'results.genfuel']);
0665 if isfield(mpc1, 'gentype')
0666     t_ok(isequal(mpc1.gentype, r.gentype), [t 'results.gentype']);
0667 else
0668     t_ok(0, [t 'results.gentype']);
0669 end
0670 if isfield(mpc1, 'genfuel')
0671     t_ok(isequal(mpc1.genfuel, r.genfuel), [t 'results.genfuel']);
0672 else
0673     t_ok(0, [t 'results.genfuel']);
0674 end
0675 
0676 t = 'DC - softlims (violated) : ';
0677 mpc = rmfield(mpc, 'softlims');
0678 mpc.softlims.RATE_A.hl_mod = 'remove';
0679 mpc.softlims.RATE_A.cost = 20;
0680 for lim = {'VMIN', 'VMAX', 'ANGMIN', 'ANGMAX', 'PMIN', 'PMAX', 'QMIN', 'QMAX'}
0681     mpc.softlims.(lim{:}).hl_mod = 'none';
0682 end
0683 r = rundcopf(mpc, mpopt1);
0684 t_ok(r.success, [t 'success']);
0685 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0686 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0687 t_is(r.f, 9106.5059, 4, [t 'f']);
0688 t_is(r.gen(:, PG), [241.3012         0   10.0000   63.6988].', 4, [t 'Pg']);
0689 t_is(r.branch(:, PF), [10; -31.3012; -121.3012; 241.3012; 0; 120; 20; -63.6988; 83.6988; -41.3012], 4, [t 'Pf']);
0690 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 20; 0; 0; 13.2992; 0; 0; 0; 0], 4, [t 'mu Pf']);
0691 t_is(r.softlims.RATE_A.overload, [0; 0; 1.3011811; 0; 0; 0; 0; 0; 0; 0], 6, [t 'softlims.RATE_A.overload']);
0692 t_is(r.softlims.RATE_A.ovl_cost, [0; 0; 26.023622; 0; 0; 0; 0; 0; 0; 0], 6, [t 'softlims.RATE_A.ovl_cost']);
0693 gen_order_check(mpc, r, t, mpopt1);
0694 
0695 t = 'savecase(fname, mpc) : ';
0696 fn = sprintf('softlims_savecase_test_%d', fix(1e8*rand));
0697 savecase(fn, mpc);
0698 mpc1 = loadcase(fn);
0699 delete([fn '.m']);
0700 t_ok(isfield(mpc1, 'softlims'), [t 'mpc.softlims']);
0701 for lm = fieldnames(mpc.softlims).'
0702     lim = lm{:};
0703     t_ok(isfield(mpc1.softlims, lim), [t 'mpc.softlims.' lim])
0704     for f = fieldnames(mpc.softlims.(lim)).'
0705         field = f{:};
0706         if any(isinf(mpc.softlims.(lim).(field)))
0707             t_ok(isequal(mpc1.softlims.(lim).(field), mpc.softlims.(lim).(field)), [t 'mpc.softlims.' lim '.' field])
0708         else
0709             t_is(mpc1.softlims.(lim).(field), mpc.softlims.(lim).(field), 5, [t 'mpc.softlims.' lim '.' field])
0710         end
0711     end
0712 end
0713 
0714 t = 'savecase(fname, results) : ';
0715 fn = sprintf('softlims_savecase_test_%d', fix(1e8*rand));
0716 savecase(fn, r);
0717 mpc1 = loadcase(fn);
0718 delete([fn '.m']);
0719 t_ok(isfield(mpc1, 'softlims'), [t 'results.softlims']);
0720 for lm = fieldnames(r.softlims).'
0721     lim = lm{:};
0722     t_ok(isfield(mpc1.softlims, lim), [t 'results.softlims.' lim])
0723     for f = fieldnames(r.softlims.(lim)).'
0724         field = f{:};
0725         if any(isinf(r.softlims.(lim).(field)))
0726             t_ok(isequal(mpc1.softlims.(lim).(field), r.softlims.(lim).(field)), [t 'results.softlims.' lim '.' field])
0727         else
0728             t_is(mpc1.softlims.(lim).(field), r.softlims.(lim).(field), 5, [t 'results.softlims.' lim '.' field])
0729         end
0730     end
0731 end
0732 
0733 %%-----  AC OPF (opf.flow_lim = 'S') -----
0734 mpc = mpc0;
0735 t = 'AC flow_lim=''S'' - hard limits : ';
0736 t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
0737 r = runopf(mpc, mpopt);
0738 t_ok(r.success, [t 'success']);
0739 t_ok(~isfield(r.softlims.RATE_A, 'overload'), [t 'no softlims.RATE_A.overload']);
0740 t_ok(~isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'no softlims.RATE_A.ovl_cost']);
0741 t_is(r.f, 9521.385584, 4, [t 'f']);
0742 t_is(r.gen(:, PG), [239.901164; 0 ; 17.312141; 66.456235], 4, [t 'Pg']);
0743 t_is(r.branch(:, PF), [17.312141; -25.063413; -115.166831; 239.901164; 0; 119.964612; 18.530059; -66.456235; 84.941080; -42.201990], 4, [t 'Pf']);
0744 t_is(r.branch(:, PT), [-17.312141; 25.166831; 119.936552; -239.901164; 0; -118.530059; -18.484844; 66.456235; -82.798010; 42.375554], 4, [t 'Pt']);
0745 t_is(r.branch(:, QF), [-2.721149; -2.842148; -16.241771; 21.275974; 0; -2.914100; -25.325409; -17.123405; 8.944864; -17.404939], 4, [t 'Qf']);
0746 t_is(r.branch(:, QT), [2.884399; -13.758229; -3.901717; 6.815818; 0; -9.674591; 8.178541; 19.603112; -32.595061; -0.042250], 4, [t 'Qt']);
0747 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 29.242772; 0; 0; 8.561015; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0748 gen_order_check(mpc, r, t, mpopt);
0749 
0750 t = 'AC flow_lim=''S'' - softlims(satisfied) : ';
0751 mpc = toggle_softlims(mpc, 'on');
0752 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0753 r = runopf(mpc, mpopt);
0754 t_ok(r.success, [t 'success']);
0755 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0756 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0757 t_is(r.f, 9521.385584, 4, [t 'f']);
0758 t_is(r.gen(:, PG), [239.901164; 0; 17.312141; 66.456235], 4, [t 'Pg']);
0759 t_is(r.branch(:, PF), [17.312141; -25.063413; -115.166831; 239.901164; 0; 119.964612; 18.530059; -66.456235; 84.941080; -42.201990], 4, [t 'Pf']);
0760 t_is(r.branch(:, PT), [-17.312141; 25.166831; 119.936552; -239.901164; 0; -118.530059; -18.484844; 66.456235; -82.798010; 42.375554], 4, [t 'Pt']);
0761 t_is(r.branch(:, QF), [-2.721149; -2.842148; -16.241771; 21.275974; 0; -2.914100; -25.325409; -17.123405; 8.944864; -17.404939], 4, [t 'Qf']);
0762 t_is(r.branch(:, QT), [2.884399; -13.758229; -3.901717; 6.815818; 0; -9.674591; 8.178541; 19.603112; -32.595061; -0.042250], 4, [t 'Qt']);
0763 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 29.242772; 0; 0; 8.561015; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0764 t_is(r.softlims.RATE_A.overload, zeros(10, 1), 12, [t 'softlims.overload']);
0765 t_is(r.softlims.RATE_A.ovl_cost, zeros(10, 1), 12, [t 'softlims.ovl_cost']);
0766 t_is(r.order.branch.status.on(r.order.int.softlims.RATE_A.idx), [3; 6; 8; 9; 10], 12, [t 'softlims.RATE_A.idx']);
0767 gen_order_check(mpc, r, t, mpopt);
0768 
0769 t = 'AC flow_lim=''S'' - softlims (violated) : ';
0770 mpc = rmfield(mpc, 'softlims');
0771 mpc.softlims.RATE_A.hl_mod = 'remove';
0772 mpc.softlims.RATE_A.cost = 20;
0773 for lim = {'VMIN', 'VMAX', 'ANGMIN', 'ANGMAX', 'PMIN', 'PMAX', 'QMIN', 'QMAX'}
0774     mpc.softlims.(lim{:}).hl_mod = 'none';
0775 end
0776 r = runopf(mpc, mpopt);
0777 t_ok(r.success, [t 'success']);
0778 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0779 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0780 t_is(r.f, 9486.265634, 4, [t 'f']);
0781 t_is(r.gen(:, PG), [243.758931; 0; 10; 70.325987], 4, [t 'Pg']);
0782 t_is(r.branch(:, PF), [10; -28.621625; -118.761245; 243.758931; 0; 119.958848; 18.527937; -70.325987; 88.808549; -38.472172], 4, [t 'Pf']);
0783 t_is(r.branch(:, PT), [-10; 28.761245; 123.8; -243.758931; 0; -118.527937; -18.482561; 70.325987; -86.527828; 38.621625], 4, [t 'Pt']);
0784 t_is(r.branch(:, QF), [3.364131; 0.552145; -12.847555; 19.471020; 0; -3.142423; -25.464124; -14.475416; 6.202740; -20.630111], 4, [t 'Qf']);
0785 t_is(r.branch(:, QT), [-3.306136; -17.152445; -6.346356; 9.488779; 0; -9.535876; 8.272676; 17.182536; -29.369889; 2.753991], 4, [t 'Qt']);
0786 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 20; 0; 0; 11.575125; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0787 t_is(r.softlims.RATE_A.overload, [0; 0; 3.962643; 0; 0; 0; 0; 0; 0; 0], 6, [t 'softlims.RATE_A.overload']);
0788 t_is(r.softlims.RATE_A.ovl_cost, [0; 0; 79.252860; 0; 0; 0; 0; 0; 0; 0], 4, [t 'softlims.RATE_A.ovl_cost']);
0789 gen_order_check(mpc, r, t, mpopt);
0790 
0791 %% -----  AC OPF (opf.flow_lim = 'I') -----
0792 mpopt = mpoption(mpopt, 'opf.flow_lim', 'I');
0793 mpc = mpc0;
0794 t = 'AC flow_lim=''I'' - hard limits : ';
0795 t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
0796 r = runopf(mpc, mpopt);
0797 t_ok(r.success, [t 'success']);
0798 t_ok(~isfield(r.softlims.RATE_A, 'overload'), [t 'no softlims.RATE_A.overload']);
0799 t_ok(~isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'no softlims.RATE_A.ovl_cost']);
0800 t_is(r.f, 9178.300537, 4, [t 'f']);
0801 t_is(r.gen(:, PG), [260.040338; 0; 10; 54.432302], 4, [t 'Pg']);
0802 t_is(r.branch(:, PF), [10; -32.676659; -122.910718; 260.040338; 0; 131.831065; 30.115930; -54.432302; 84.451894; -42.475047], 4, [t 'Pf']);
0803 t_is(r.branch(:, PT), [-10; 32.910718; 128.209273; -260.040338; 0; -130.115930; -30.019591; 54.432302; -82.524953; 42.676659], 4, [t 'Pt']);
0804 t_is(r.branch(:, QF), [27.824349; 14.237742; 1.341441; 7.733221; 0; -4.887428; -29.462755; -4.743706; -7.797128; -31.778587], 4, [t 'Qf']);
0805 t_is(r.branch(:, QT), [-27.408203; -31.341441; -20.438656; 25.326084; 0; -5.537245; 12.540834; 6.294583; -18.221413; 13.170461], 4, [t 'Qt']);
0806 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 0; 0; 0; 20.114712; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0807 gen_order_check(mpc, r, t, mpopt);
0808 
0809 t = 'AC flow_lim=''I'' - softlims(satisfied) : ';
0810 mpc = toggle_softlims(mpc, 'on');
0811 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0812 r = runopf(mpc, mpopt);
0813 t_ok(r.success, [t 'success']);
0814 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0815 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0816 t_is(r.f, 9178.300537, 4, [t 'f']);
0817 t_is(r.gen(:, PG), [260.040338; 0; 10; 54.432302], 4, [t 'Pg']);
0818 t_is(r.branch(:, PF), [10; -32.676659; -122.910718; 260.040338; 0; 131.831065; 30.115930; -54.432302; 84.451894; -42.475047], 4, [t 'Pf']);
0819 t_is(r.branch(:, PT), [-10; 32.910718; 128.209273; -260.040338; 0; -130.115930; -30.019591; 54.432302; -82.524953; 42.676659], 4, [t 'Pt']);
0820 t_is(r.branch(:, QF), [27.824349; 14.237742; 1.341441; 7.733221; 0; -4.887428; -29.462755; -4.743706; -7.797128; -31.778587], 4, [t 'Qf']);
0821 t_is(r.branch(:, QT), [-27.408203; -31.341441; -20.438656; 25.326084; 0; -5.537245; 12.540834; 6.294583; -18.221413; 13.170461], 4, [t 'Qt']);
0822 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 0; 0; 0; 20.114712; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0823 t_is(r.softlims.RATE_A.overload, zeros(10, 1), 12, [t 'softlims.RATE_A.overload']);
0824 t_is(r.softlims.RATE_A.ovl_cost, zeros(10, 1), 12, [t 'softlims.RATE_A.ovl_cost']);
0825 t_is(r.order.branch.status.on(r.order.int.softlims.RATE_A.idx), [3; 6; 8; 9; 10], 12, [t 'softlims.RATE_A.idx']);
0826 gen_order_check(mpc, r, t, mpopt);
0827 
0828 t = 'AC flow_lim=''I'' - softlims (violated) : ';
0829 mpc = rmfield(mpc, 'softlims');
0830 mpc.softlims.RATE_A.hl_mod = 'remove';
0831 mpc.softlims.RATE_A.cost = 15;
0832 for lim = {'VMIN', 'VMAX', 'ANGMIN', 'ANGMAX', 'PMIN', 'PMAX', 'QMIN', 'QMAX'}
0833     mpc.softlims.(lim{:}).hl_mod = 'none';
0834 end
0835 r = runopf(mpc, mpopt);
0836 t_ok(r.success, [t 'success']);
0837 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0838 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0839 t_is(r.f, 9146.413838, 4, [t 'f']);
0840 t_is(r.gen(:, PG), [270; 0; 10; 44.862996], 4, [t 'Pg']);
0841 t_is(r.branch(:, PF), [10; -34.955827; -125.208395; 270; 0; 139.280487; 37.364683; -44.862996; 82.094229; -44.742338], 4, [t 'Pf']);
0842 t_is(r.branch(:, PT), [-10; 35.208395; 130.719513; -270; 0; -137.364683; -37.231233; 44.862996; -80.257662; 44.955827], 4, [t 'Pt']);
0843 t_is(r.branch(:, QF), [25.262645; 13.437313; 0.303801; 13.552057; 0; -3.645909; -29.947558; -7.234346; -6.145528; -29.826268], 4, [t 'Qf']);
0844 t_is(r.branch(:, QT), [-24.907470; -30.303801; -18.341454; 21.987363; 0; -5.052442; 13.379873; 8.309624; -20.173732; 11.470157], 4, [t 'Qt']);
0845 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 6.260861; 0; 0; 15; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0846 t_is(r.softlims.RATE_A.overload, [0; 0; 0; 0; 0; 6.792934; 0; 0; 0; 0], 6, [t 'softlims.RATE_A.overload']);
0847 t_is(r.softlims.RATE_A.ovl_cost, [0; 0; 0; 0; 0; 101.894009; 0; 0; 0; 0], 4, [t 'softlims.RATE_A.ovl_cost']);
0848 gen_order_check(mpc, r, t, mpopt);
0849 
0850 %%-----  AC OPF (opf.flow_lim = '2') -----
0851 mpopt = mpoption(mpopt, 'opf.flow_lim', '2');
0852 mpc = mpc0;
0853 t = 'AC flow_lim=''2'' - hard limits : ';
0854 t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
0855 r = runopf(mpc, mpopt);
0856 t_ok(r.success, [t 'success']);
0857 t_ok(~isfield(r.softlims.RATE_A, 'overload'), [t 'no softlims.RATE_A.overload']);
0858 t_ok(~isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'no softlims.RATE_A.ovl_cost']);
0859 t_is(r.f, 9513.613051, 4, [t 'f']);
0860 t_is(r.gen(:, PG), [240; 0; 17.759246; 65.641269], 4, [t 'Pg']);
0861 t_is(r.branch(:, PF), [17.759246; -25.216499; -115.346644; 240; 0; 120; 18.577311; -65.641269; 84.170657; -42.784248], 4, [t 'Pf']);
0862 t_is(r.branch(:, PT), [-17.759246; 25.346644; 120; -240; 0; -118.577311; -18.529387; 65.641269; -82.215752; 42.975745], 4, [t 'Pt']);
0863 t_is(r.branch(:, QF), [15.646152; 6.577259; -6.087866; 8.021258; 0; -4.520662; -26.623563; -6.687069; -2.629290; -27.085546], 4, [t 'Qf']);
0864 t_is(r.branch(:, QT), [-15.370220; -23.912134; -15.548682; 20.069344; 0; -8.376437; 9.316359; 8.954090; -22.914454; 8.792961], 4, [t 'Qt']);
0865 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 29.248033; 0; 0; 8.417115; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0866 gen_order_check(mpc, r, t, mpopt);
0867 
0868 t = 'AC flow_lim=''2'' - softlims(satisfied) : ';
0869 mpc = toggle_softlims(mpc, 'on');
0870 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0871 r = runopf(mpc, mpopt);
0872 t_ok(r.success, [t 'success']);
0873 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0874 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0875 t_is(r.f, 9513.613051, 4, [t 'f']);
0876 t_is(r.gen(:, PG), [240; 0; 17.759246; 65.641269], 4, [t 'Pg']);
0877 t_is(r.branch(:, PF), [17.759246; -25.216499; -115.346644; 240; 0; 120; 18.577311; -65.641269; 84.170657; -42.784248], 4, [t 'Pf']);
0878 t_is(r.branch(:, PT), [-17.759246; 25.346644; 120; -240; 0; -118.577311; -18.529387; 65.641269; -82.215752; 42.975745], 4, [t 'Pt']);
0879 t_is(r.branch(:, QF), [15.646152; 6.577259; -6.087866; 8.021258; 0; -4.520662; -26.623563; -6.687069; -2.629290; -27.085546], 4, [t 'Qf']);
0880 t_is(r.branch(:, QT), [-15.370220; -23.912134; -15.548682; 20.069344; 0; -8.376437; 9.316359; 8.954090; -22.914454; 8.792961], 4, [t 'Qt']);
0881 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 29.248033; 0; 0; 8.417115; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0882 t_is(r.softlims.RATE_A.overload, zeros(10, 1), 12, [t 'softlims.RATE_A.overload']);
0883 t_is(r.softlims.RATE_A.ovl_cost, zeros(10, 1), 12, [t 'softlims.RATE_A.ovl_cost']);
0884 t_is(r.order.branch.status.on(r.order.int.softlims.RATE_A.idx), [3; 6; 8; 9; 10], 12, [t 'softlims.RATE_A.idx']);
0885 gen_order_check(mpc, r, t, mpopt);
0886 
0887 t = 'AC flow_lim=''2'' - softlims (violated) : ';
0888 mpc = rmfield(mpc, 'softlims');
0889 mpc.softlims.RATE_A.hl_mod = 'remove';
0890 mpc.softlims.RATE_A.cost = 20;
0891 for lim = {'VMIN', 'VMAX', 'ANGMIN', 'ANGMAX', 'PMIN', 'PMAX', 'QMIN', 'QMAX'}
0892     mpc.softlims.(lim{:}).hl_mod = 'none';
0893 end
0894 r = runopf(mpc, mpopt);
0895 t_ok(r.success, [t 'success']);
0896 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0897 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0898 t_is(r.f, 9476.854715, 4, [t 'f']);
0899 t_is(r.gen(:, PG), [244.077740; 0; 10; 69.833910], 4, [t 'Pg']);
0900 t_is(r.branch(:, PF), [10; -28.933383; -119.111239; 244.077740; 0; 120; 18.578292; -69.833910; 88.362736; -38.762267], 4, [t 'Pf']);
0901 t_is(r.branch(:, PT), [-10; 29.111239; 124.077740; -244.077740; 0; -118.578292; -18.528826; 69.833910; -86.237733; 38.933383], 4, [t 'Pt']);
0902 t_is(r.branch(:, QF), [22.204979; 10.325903; -2.434897; 5.980065; 0; -5.159694; -27.240912; -4.815545; -5.105567; -30.250169], 4, [t 'Qf']);
0903 t_is(r.branch(:, QT), [-21.917920; -27.565103; -17.970864; 23.130558; 0; -7.759088; 9.921112; 7.362539; -19.749831; 11.592017], 4, [t 'Qt']);
0904 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 20; 0; 0; 11.526783; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0905 t_is(r.softlims.RATE_A.overload, [0; 0; 4.07774; 0; 0; 0; 0; 0; 0; 0], 6, [t 'softlims.RATE_A.overload']);
0906 t_is(r.softlims.RATE_A.ovl_cost, [0; 0; 81.554809; 0; 0; 0; 0; 0; 0; 0], 4, [t 'softlims.RATE_A.ovl_cost']);
0907 gen_order_check(mpc, r, t, mpopt);
0908 
0909 %%-----  AC OPF (opf.flow_lim = 'P') -----
0910 mpopt = mpoption(mpopt, 'opf.flow_lim', 'P');
0911 mpc = mpc0;
0912 t = 'AC flow_lim=''P'' - hard limits : ';
0913 t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
0914 r = runopf(mpc, mpopt);
0915 t_ok(r.success, [t 'success']);
0916 t_ok(~isfield(r.softlims.RATE_A, 'overload'), [t 'no softlims.RATE_A.overload']);
0917 t_ok(~isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'no softlims.RATE_A.ovl_cost']);
0918 t_is(r.f, 9513.613051, 4, [t 'f']);
0919 t_is(r.gen(:, PG), [240; 0; 17.759246; 65.641269], 4, [t 'Pg']);
0920 t_is(r.branch(:, PF), [17.759246; -25.216499; -115.346644; 240; 0; 120; 18.577311; -65.641269; 84.170657; -42.784248], 4, [t 'Pf']);
0921 t_is(r.branch(:, PT), [-17.759246; 25.346644; 120; -240; 0; -118.577311; -18.529387; 65.641269; -82.215752; 42.975745], 4, [t 'Pt']);
0922 t_is(r.branch(:, QF), [15.646152; 6.577259; -6.087866; 8.021258; 0; -4.520662; -26.623563; -6.687069; -2.629290; -27.085546], 4, [t 'Qf']);
0923 t_is(r.branch(:, QT), [-15.370220; -23.912134; -15.548682; 20.069344; 0; -8.376437; 9.316359; 8.954090; -22.914454; 8.792961], 4, [t 'Qt']);
0924 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 29.248033; 0; 0; 8.417115; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0925 gen_order_check(mpc, r, t, mpopt);
0926 
0927 t = 'AC flow_lim=''P'' - softlims(satisfied) : ';
0928 mpc = toggle_softlims(mpc, 'on');
0929 t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
0930 r = runopf(mpc, mpopt);
0931 t_ok(r.success, [t 'success']);
0932 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0933 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0934 t_is(r.f, 9513.613051, 4, [t 'f']);
0935 t_is(r.gen(:, PG), [240; 0; 17.759246; 65.641269], 4, [t 'Pg']);
0936 t_is(r.branch(:, PF), [17.759246; -25.216499; -115.346644; 240; 0; 120; 18.577311; -65.641269; 84.170657; -42.784248], 4, [t 'Pf']);
0937 t_is(r.branch(:, PT), [-17.759246; 25.346644; 120; -240; 0; -118.577311; -18.529387; 65.641269; -82.215752; 42.975745], 4, [t 'Pt']);
0938 t_is(r.branch(:, QF), [15.646152; 6.577259; -6.087866; 8.021258; 0; -4.520662; -26.623563; -6.687069; -2.629290; -27.085546], 4, [t 'Qf']);
0939 t_is(r.branch(:, QT), [-15.370220; -23.912134; -15.548682; 20.069344; 0; -8.376437; 9.316359; 8.954090; -22.914454; 8.792961], 4, [t 'Qt']);
0940 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 29.248033; 0; 0; 8.417115; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0941 t_is(r.softlims.RATE_A.overload, zeros(10, 1), 12, [t 'softlims.RATE_A.overload']);
0942 t_is(r.softlims.RATE_A.ovl_cost, zeros(10, 1), 12, [t 'softlims.RATE_A.ovl_cost']);
0943 t_is(r.order.branch.status.on(r.order.int.softlims.RATE_A.idx), [3; 6; 8; 9; 10], 12, [t 'softlims.RATE_A.idx']);
0944 gen_order_check(mpc, r, t, mpopt);
0945 
0946 t = 'AC flow_lim=''P'' - softlims (violated) : ';
0947 mpc = rmfield(mpc, 'softlims');
0948 mpc.softlims.RATE_A.hl_mod = 'remove';
0949 mpc.softlims.RATE_A.cost = 20;
0950 for lim = {'VMIN', 'VMAX', 'ANGMIN', 'ANGMAX', 'PMIN', 'PMAX', 'QMIN', 'QMAX'}
0951     mpc.softlims.(lim{:}).hl_mod = 'none';
0952 end
0953 r = runopf(mpc, mpopt);
0954 t_ok(r.success, [t 'success']);
0955 t_ok(isfield(r.softlims.RATE_A, 'overload'), [t 'softlims.RATE_A.overload exists']);
0956 t_ok(isfield(r.softlims.RATE_A, 'ovl_cost'), [t 'softlims.RATE_A.ovl_cost exists']);
0957 t_is(r.f, 9476.854715, 4, [t 'f']);
0958 t_is(r.gen(:, PG), [244.077740; 0; 10; 69.833910], 4, [t 'Pg']);
0959 t_is(r.branch(:, PF), [10; -28.933383; -119.111239; 244.077740; 0; 120; 18.578292; -69.833910; 88.362736; -38.762267], 4, [t 'Pf']);
0960 t_is(r.branch(:, PT), [-10; 29.111239; 124.077740; -244.077740; 0; -118.578292; -18.528826; 69.833910; -86.237733; 38.933383], 4, [t 'Pt']);
0961 t_is(r.branch(:, QF), [22.204979; 10.325903; -2.434897; 5.980065; 0; -5.159694; -27.240912; -4.815545; -5.105567; -30.250169], 4, [t 'Qf']);
0962 t_is(r.branch(:, QT), [-21.917920; -27.565103; -17.970864; 23.130558; 0; -7.759088; 9.921112; 7.362539; -19.749831; 11.592017], 4, [t 'Qt']);
0963 t_is(r.branch(:, MU_SF)+r.branch(:, MU_ST), [0; 0; 20; 0; 0; 11.526783; 0; 0; 0; 0], 4, [t 'mu Sf+St']);
0964 t_is(r.softlims.RATE_A.overload, [0; 0; 4.07774; 0; 0; 0; 0; 0; 0; 0], 6, [t 'softlims.RATE_A.overload']);
0965 t_is(r.softlims.RATE_A.ovl_cost, [0; 0; 81.554809; 0; 0; 0; 0; 0; 0; 0], 4, [t 'softlims.RATE_A.ovl_cost']);
0966 gen_order_check(mpc, r, t, mpopt);
0967 
0968 if have_fcn('octave')
0969     warning(s1.state, file_in_path_warn_id);
0970 end
0971 warning(s2.state, sing_matrix_warn_id);
0972 
0973 t_end;
0974 
0975 
0976 function overload_loop(r, t, yn, lst, isDC)
0977 %% r is the result structure
0978 %% t is the test string
0979 %% yn is whether to check if it is (1) or is not (0) a field
0980 %% lst is a cell of limit names
0981 %%     if yn == 1 i.e. checking if limits exist then this is a list of
0982 %%     limits to check
0983 %%     if yn == 0 i.e. checking that the limits do not exist, this is
0984 %%     a list of limits to exclude
0985 
0986 if nargin < 5
0987     isDC = 0;
0988     if nargin < 4
0989         lst = {};
0990     end
0991 end
0992 
0993 if isDC
0994     mpopt = mpoption('model', 'DC');
0995 else
0996     mpopt = mpoption('model', 'AC');
0997 end
0998 lims_default = fieldnames(softlims_lim2mat(mpopt)).';
0999 
1000 if ~yn
1001     lst = lims_default(~ismember(lims_default, lst));
1002 else
1003     if isempty(lst)
1004         lst = lims_default;
1005     else
1006         lst = lims_default(ismember(lims_default, lst));
1007     end
1008 end
1009 for lm = lst
1010     lim = lm{1};
1011     if yn
1012         t_ok(isfield(r.softlims.(lim), 'overload'), [t sprintf('softlims.%s.overload exists', lim)]);
1013         t_ok(isfield(r.softlims.(lim), 'ovl_cost'), [t sprintf('softlims.%s.ovl_cost exists', lim)]);
1014     else
1015         t_ok(~isfield(r.softlims.(lim), 'overload'), [t sprintf('no softlims.%s.overload', lim)]);
1016         t_ok(~isfield(r.softlims.(lim), 'ovl_cost'), [t sprintf('no softlims.%s.ovl_cost', lim)]);
1017     end
1018 end
1019 
1020 function r = toggle_run_check(mpc, mpopt, t, on_off)
1021 %% checks the softlims status of mpc, runs the opf, checks for success and
1022 %% returns the results structure
1023 
1024 if ~on_off
1025     t_ok(~toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 0');
1026 else
1027     t_ok(toggle_softlims(mpc, 'status'), 'toggle_softlims(mpc, ''status'') == 1');
1028 end
1029 r = runopf(mpc, mpopt);
1030 t_ok(r.success, [t 'success']);
1031 
1032 function mu_cost_test(r, t, mpopt)
1033 %% Tests whether the shadow price on violations matches the respective
1034 %% softlim cost. The shadow price should equal the softlim cost when the
1035 %% violation variable is used but the constraint is not binding. i.e. there is
1036 %% a non-zero overload but the violation variable is not at its own limit.
1037 %% the function therefore searches for any non-zero overload (mumask1)
1038 %% that is also below the violation variables upper bound stored in s.ub
1039 %% (mumask2). The cost of these variables is compared to the respective
1040 %% shadow prices.
1041 
1042 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
1043     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
1044 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
1045     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
1046     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
1047 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
1048     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
1049     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
1050 
1051 %% structures used to index into softlims in a loop
1052 lims = softlims_lim2mat(mpopt);
1053 
1054 vv = r.om.get_idx();
1055 [x0, xmin, xmax] = r.om.params_var();
1056 
1057 for lm = fieldnames(lims).'
1058     lim = lm{:};
1059     mat_name = lims.(lim).mat_name;
1060     if ~isfield(r.softlims, lim)
1061         continue
1062     end
1063     if strcmp(r.softlims.(lim).hl_mod, 'none')
1064         continue
1065     end
1066     s = r.softlims.(lim);
1067 
1068     varname = ['s_' lower(lim)];
1069     ub = xmax(vv.i1.(varname):vv.iN.(varname));
1070     switch lim
1071         case {'RATE_A', 'PMAX', 'PMIN', 'QMAX', 'QMIN'}
1072             ub = ub * r.baseMVA;
1073         case {'ANGMAX', 'ANGMIN'}
1074             ub = ub * 180/pi;
1075     end
1076 
1077     %% violation variable is non zero
1078     mumask1 = s.overload > 1e-6;
1079     %% ensure that overloads are not at the violation variable boundary since
1080     %% then the shadow price can take on any value again.
1081     mumask2 = true(size(mumask1));
1082     mumask2(s.idx) = s.overload(s.idx) < ub;
1083     
1084     mumask = mumask1 & mumask2;
1085     
1086     %% linear cost
1087     cst = zeros(size(mumask1));
1088     cst(s.idx) = s.cost;
1089     cst = cst(mumask); %keep only relevant entries
1090     
1091     if strcmp(lim, 'RATE_A')
1092         mu = sum(r.branch(mumask, MU_SF:MU_ST));
1093     else
1094         muidx = eval(['MU_' lim]);
1095         mu = r.(mat_name)(mumask, muidx);
1096     end
1097     
1098     t_is(mu,cst,4,[t 'mu ' lim '=cost'])
1099 end
1100 
1101 function gen_order_check(mpc, r, t, mpopt)
1102 %% Make sure the ordering of generators in input case and result
1103 %% case is the same. Also make sure that any overloads are correctly
1104 %% reflected in the difference between the generation value and
1105 %% the respective limit
1106 
1107 if nargin < 4
1108     isAC = 1;
1109 else
1110     isAC = ~(~isempty(mpopt) && isfield(mpopt, 'model') && strcmp(mpopt.model, 'DC'));
1111 end
1112 
1113 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
1114     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
1115     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
1116 
1117 glist = {'P'};
1118 if isAC
1119     t_is(mpc.gen(:,QMAX), r.gen(:,QMAX), 6, [t 'matching QMAX'])
1120     t_is(mpc.gen(:,QMIN), r.gen(:,QMIN), 6, [t 'matching QMIN'])
1121     glist = {glist{:}, 'Q'};
1122 end
1123 t_is(mpc.gen(:,PMAX), r.gen(:,PMAX), 6, [t 'matching PMAX'])
1124 t_is(mpc.gen(:,PMIN), r.gen(:,PMIN), 6, [t 'matching PMIN'])
1125 t_is(mpc.gen(:,GEN_STATUS), r.gen(:,GEN_STATUS), 6, [t 'matching gen status'])
1126 
1127 on = r.gen(:,GEN_STATUS) > 0;
1128 for gg = glist
1129     g = gg{:};
1130     if isfield(r, 'softlims')
1131         gidx = eval([g 'G']);
1132         gmax = eval([g 'MAX']);
1133         gmin = eval([g 'MIN']);
1134         if isfield(r.softlims.([g 'MAX']), 'overload')
1135             mask = (r.gen(:,gidx) - r.gen(:,gmax) > 0) & on;
1136             t_is(r.softlims.([g 'MAX']).overload(mask), r.gen(mask, gidx) - r.gen(mask,gmax), 4, [t g 'G-' g 'MAX= ' g 'MAX overload'])
1137         end
1138         if isfield(r.softlims.([g 'MIN']), 'overload')
1139             mask = (r.gen(:,gmin) - r.gen(:,gidx) > 0) & on;
1140             t_is(r.softlims.([g 'MIN']).overload(mask), r.gen(mask, gmin) - r.gen(mask,gidx), 4, [t g 'MIN-' g 'G= ' g 'MIN overload'])
1141         end
1142     end
1143 end
1144 
1145 
1146 %%-----  softlims_lim2mat  --------------------------------------------
1147 function lim2mat = softlims_lim2mat(mpopt)
1148 
1149 %% define named indices into data matrices
1150 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
1151     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
1152 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
1153     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
1154     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
1155 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
1156     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
1157     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
1158 
1159 if nargin < 1
1160     mpopt = [];
1161 end
1162 if ~isempty(mpopt) && isfield(mpopt, 'model') && strcmp(mpopt.model, 'DC')
1163     lim2mat = struct(...
1164         'PMAX',   struct('mat_name', 'gen',    'col', PMAX,   'dir',  1 ), ...
1165         'PMIN',   struct('mat_name', 'gen',    'col', PMIN,   'dir', -1 ), ...
1166         'RATE_A', struct('mat_name', 'branch', 'col', RATE_A, 'dir',  1 ), ...
1167         'ANGMAX', struct('mat_name', 'branch', 'col', ANGMAX, 'dir',  1 ), ...
1168         'ANGMIN', struct('mat_name', 'branch', 'col', ANGMIN, 'dir', -1 ) ...
1169     );
1170 else
1171     lim2mat = struct(...
1172         'VMAX',   struct('mat_name', 'bus',    'col', VMAX,   'dir',  1 ), ...
1173         'VMIN',   struct('mat_name', 'bus',    'col', VMIN,   'dir', -1 ), ...
1174         'PMAX',   struct('mat_name', 'gen',    'col', PMAX,   'dir',  1 ), ...
1175         'PMIN',   struct('mat_name', 'gen',    'col', PMIN,   'dir', -1 ), ...
1176         'QMAX',   struct('mat_name', 'gen',    'col', QMAX,   'dir',  1 ), ...
1177         'QMIN',   struct('mat_name', 'gen',    'col', QMIN,   'dir', -1 ), ...
1178         'RATE_A', struct('mat_name', 'branch', 'col', RATE_A, 'dir',  1 ), ...
1179         'ANGMAX', struct('mat_name', 'branch', 'col', ANGMAX, 'dir',  1 ), ...
1180         'ANGMIN', struct('mat_name', 'branch', 'col', ANGMIN, 'dir', -1 ) ...
1181     );
1182 end

Generated on Mon 24-Jun-2019 15:58:45 by m2html © 2005