Home > matpower7.1 > extras > syngrid > lib > sgvm_add_shunts.m

sgvm_add_shunts

PURPOSE ^

SGVM_ADD_SHUNTS add shunt elements to MPC to satisfy voltage constraints

SYNOPSIS ^

function [out, bsh] = sgvm_add_shunts(mpc, mpopt, opt)

DESCRIPTION ^

SGVM_ADD_SHUNTS add shunt elements to MPC to satisfy voltage constraints
   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC)
   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC, MPOPT)
   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC, MPOPT, OPT)
   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC, [], OPT)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [out, bsh] = sgvm_add_shunts(mpc, mpopt, opt)
0002 %SGVM_ADD_SHUNTS add shunt elements to MPC to satisfy voltage constraints
0003 %   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC)
0004 %   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC, MPOPT)
0005 %   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC, MPOPT, OPT)
0006 %   [OUT, BSH] = SGVM_ADD_SHUNTS(MPC, [], OPT)
0007 
0008 %   SynGrid
0009 %   Copyright (c) 2018, Power Systems Engineering Research Center (PSERC)
0010 %   by Eran Schweitzer, Arizona State University
0011 %
0012 %   This file is part of SynGrid.
0013 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0014 
0015 if nargin < 3
0016     opt = struct();
0017     if nargin < 2
0018         % copy mpoptions from syngrid options
0019         mpopt = sg_options();
0020         mpopt = mpopt.mpopt;
0021     end
0022 elseif isempty(mpopt)
0023     % copy mpoptions from syngrid options
0024     mpopt = sg_options();
0025     mpopt = mpopt.mpopt;
0026 end
0027 opt = opt_default(opt);
0028 tmag = opt.tmag;
0029 shift_in = opt.shift_in;
0030 shunt_max = opt.shunt_max;
0031 soft_ratea= opt.soft_ratea;
0032 mpopt.opf.softlims.default = 0; %required for algorithm to work
0033 %%
0034 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0035     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0036 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0037     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0038     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0039 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0040 
0041 nb = size(mpc.bus,1);
0042 ng = size(mpc.gen,1);
0043 
0044 if any(mpc.bus(:,BUS_I) ~= (1:nb)')
0045     error('sgvm_add_shunts: bus matrix needs to have consecutive bus numbering.')
0046 end
0047 out = mpc; %save output mpc before modifications
0048 %% tighten voltage limits slightely
0049 % hopefully helps avoid edge cases
0050 mpc.bus(:,VMAX) = mpc.bus(:,VMAX) - shift_in;
0051 mpc.bus(:,VMIN) = mpc.bus(:,VMIN) + shift_in;
0052 %% add ficticious generators at each bus for VAr support
0053 
0054 tmpgen = (1:nb)';
0055 ngtmp  = nb;
0056 new_gen = zeros(ngtmp, size(mpc.gen,2));
0057 new_gen(:,[GEN_BUS, VG, MBASE, GEN_STATUS]) = [tmpgen, ones(ngtmp,1), mpc.baseMVA*ones(ngtmp,1), ones(ngtmp,1)];
0058 mpc.gen = [mpc.gen; new_gen];
0059 
0060 new_gencost = zeros(ngtmp, size(mpc.gencost,2));
0061 new_gencost(:,[MODEL, NCOST, COST]) = [2*ones(ngtmp,1), 2*ones(ngtmp,1), zeros(ngtmp,1)];
0062 
0063 mpc.gencost = [mpc.gencost; new_gencost];
0064 if isfield(mpc, 'genfuel')
0065     mpc.genfuel = vertcat(mpc.genfuel, ...
0066             cellfun(@(x) 'other', num2cell(1:ngtmp), 'UniformOutput', 0).');
0067 end
0068 if isfield(mpc, 'gentype')
0069     mpc.gentype = vertcat(mpc.gentype, ...
0070             cellfun(@(x) 'OT', num2cell(1:ngtmp), 'UniformOutput', 0).');
0071 end
0072 
0073 %% softlimits
0074 if isfield(mpc, 'softlims')
0075     mpc = rmfield(mpc, 'softlims');
0076 end
0077 if soft_ratea
0078     mpc.softlims.RATE_A.hl_mod = 'remove';
0079 end
0080 current_shunt = mpc.bus(:, BS);
0081 qmax_lim = shunt_max - current_shunt;
0082 idx = find(qmax_lim > 0);
0083 mpc.softlims.QMAX   = struct('hl_mod', 'replace', 'idx', ng+idx, 'hl_val', qmax_lim(idx));%, 'cost', 100);
0084 
0085 qmin_lim = current_shunt - shunt_max;
0086 idx = find(qmin_lim < 0);
0087 mpc.softlims.QMIN   = struct('hl_mod', 'replace', 'idx', ng+idx, 'hl_val', qmin_lim(idx));%, 'cost', 100);
0088 %mpc.softlims.QMAX   = struct('hl_mod', 'replace', 'idx', (ng+1:ng+ngtmp)', 'hl_val',  shunt_max, 'cost', 100);
0089 %mpc.softlims.QMIN   = struct('hl_mod', 'replace', 'idx', (ng+1:ng+ngtmp)', 'hl_val', -shunt_max, 'cost', 100);
0090 
0091 %% solve opf
0092 if ~toggle_softlims(mpc, 'status')
0093     mpc = toggle_softlims(mpc,'on');
0094 end
0095 r   = runopf(mpc,mpopt);
0096 
0097 if ~r.success
0098   if ~isinf(shunt_max)
0099     warning('sgvm_add_shunts: OPF with Qg softlimits failed to converge. Removing shunt limits.')
0100     opt.shunt_max = Inf;
0101     [out, bsh] = sgvm_add_shunts(out, mpopt, opt);
0102     return
0103   elseif ~soft_ratea
0104     warning('sgvm_add_shunts: OPF with Qg softlimits failed to converge. Adding soft branch limits.')
0105     opt.soft_ratea = 1;
0106     [out, bsh] = sgvm_add_shunts(out, mpopt, opt);
0107     return
0108   end
0109   warning('sgvm_add_shunts: No possible solution found! (Inf shunt limits and branch limits attempted).')
0110   out = r;
0111   bsh = zeros(nb,1);
0112   return
0113 end
0114 
0115 if opt.verbose > 1
0116   fprintf('Result in sgvm_add_shunts:\n')
0117   printpf(r)
0118 end
0119 %% Convert generators to shunt elements
0120 bsh = (r.softlims.QMAX.overload(ng+1:end) - r.softlims.QMIN.overload(ng+1:end))./r.bus(:,VM).^2;
0121 
0122 % apply minimum magnitude threshold of tmag
0123 mask = (abs(bsh) > 0) & (abs(bsh) < tmag);
0124 bsh(mask) = sign(bsh(mask))*tmag;
0125 
0126 %% add shunts to case
0127 %out.bus(:,BS) = out.bus(:,BS) +  bsh;
0128 r.bus(:,BS) = r.bus(:,BS) + bsh;
0129 
0130 %% update out with power-flow results in r
0131 out = update_out(out, r, ng);
0132 
0133 %% utility functions
0134 function opt = opt_default(opt)
0135 %% setup default options
0136 optdef = sgvm_shuntsopts();
0137 
0138 if ~isempty(opt)
0139     opt = nested_struct_copy(optdef, opt);
0140 else
0141     opt = optdef;
0142 end
0143 
0144 function out = update_out(out, r, ng)
0145 %% update the output mpc case with the powerflow results in r
0146 define_constants;
0147 
0148 r.bus(:,[VMAX, VMIN] ) = out.bus(:,[VMAX, VMIN]);
0149 r.gen = r.gen(1:ng,:);
0150 r.gencost = r.gencost(1:ng, :);
0151 out = r;
0152 %%------ bus matrix -------------------
0153 %out.bus(:,[VM,VA]) = r.bus(:,[VM, VA]);
0154 %out.bus = [out.bus(:,1:13), r.bus(:, 14:end)];
0155 %
0156 %%------ branch matrix ---------------
0157 %out.branch = [out.branch(:,1:13), r.branch(:,14:end)];
0158 %
0159 %%----- gen matrix ------------------
0160 %out.gen(:,[PG,QG,VG]) = r.gen(1:ng, [PG,QG,VG]);
0161 %out.gen = [out.gen(:,1:21), r.gen(1:ng, 22:end)];

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