SGVM_NODEPERM_INIT Initial node permutation (following branch assignment) MPC = SGVM_NODEPERM_INIT(MPC) Generator buses are targeted for buses with *larger* driving point impedances, Zdr. Within the range of *larger* Zdr, larger generators tend towards the *smaller* entries.
0001 function mpc = sgvm_nodeperm_init(mpc) 0002 %SGVM_NODEPERM_INIT Initial node permutation (following branch assignment) 0003 % MPC = SGVM_NODEPERM_INIT(MPC) 0004 % 0005 % Generator buses are targeted for buses with *larger* driving point 0006 % impedances, Zdr. Within the range of *larger* Zdr, larger generators 0007 % tend towards the *smaller* entries. 0008 0009 % SynGrid 0010 % Copyright (c) 2018, Power Systems Engineering Research Center (PSERC) 0011 % by Eran Schweitzer, Arizona State University 0012 % 0013 % This file is part of SynGrid. 0014 % Covered by the 3-clause BSD License (see LICENSE file for details). 0015 0016 %% some constants 0017 define_constants; 0018 nb = size(mpc.bus,1); 0019 ng = size(mpc.gen,1); 0020 0021 %% driving point impedances 0022 Zdr = abs(sgvm_getZdr(mpc)); 0023 [Zdrsorted, idxz] = sort(Zdr); 0024 0025 %% generator capacity 0026 gmap = sparse(mpc.gen(:,GEN_BUS),1:ng, 1, nb, ng); 0027 gvect = gmap*mpc.gen(:,PMAX); % nb x 1: generation capacity at each node 0028 [idxp,~,Pcap] = find(gvect); % extract non-zero terms 0029 ngp = length(idxp); % number of generators with non-zero PMAX 0030 dirtmp = {'descend', 'desc'}; 0031 failcnt = 0; 0032 for k = 1:2 0033 try 0034 [Pcap, tmp] = sort(Pcap, dirtmp{k}); % sort generation in descending order 0035 break 0036 catch 0037 failcnt = failcnt + 1; 0038 end 0039 end 0040 if failcnt == 2 0041 error('sgvm_nodeperm_init: something went wrong when sorting Pcap, neither ''descend'' nor ''desc'' worked') 0042 end 0043 idxp = idxp(tmp); % sort generator bus index vector to match the Pcap vector 0044 0045 %% Corrolate gen to zdr 0046 nmap = zeros(nb,1); %initialize new mapping 0047 % % idxz(end-ng+1) are the indecies of the ng largest Zdr in INCREASING order 0048 % % idxp are the bus indecies of the generators in DECREASING order 0049 % nmap(idxp) = idxz(end-ng+1:end); 0050 % %% add some "noise" 0051 % ngswap = round(0.25*ng); 0052 % usedidx = nmap(idxp); 0053 % genidx = 0; 0054 % count = 0; 0055 % while true 0056 % newidx = randi(nb); 0057 % if genidx = 0; 0058 % genidx = idxp(randi(ng)); 0059 % end 0060 % if ~ismember(newidx,usedidx) 0061 % % newly selected bus does not already have a generator assigned 0062 % nmap(genidx) = newidx; 0063 % genidx = 0; 0064 % else 0065 % % newly selected bus already has a generator assigned 0066 % tmp = find(nmap == newidx ); % index of generator being relpaced 0067 % nmap(genidx) = newidx; % map generator to new bus 0068 % genidx = tmp; % this way in next round the doulbed bus numbering will be handled 0069 % end 0070 % 0071 % % update list of used buses 0072 % usedidx = nmap(idxp); 0073 % count = count + 1; 0074 % if (count >= ngswap) && genidx = 0; 0075 % break 0076 % end 0077 % end 0078 0079 % idxtmp = unique(round(betarnd(8,3,ngp,1)*nb)); 0080 idxtmp = unique(round(sgvm_beta_variate(ngp, 8, 3)*nb)); 0081 if ngp - length(idxtmp) > 0 0082 ptr = length(idxtmp) + 1; 0083 idxtmp = [idxtmp; zeros(ngp - length(idxtmp), 1)]; 0084 % while length(idxtmp) < ngp 0085 while ptr <= ngp 0086 % tmp = round(betarnd(8,3)*nb); 0087 tmp = round(sgvm_beta_variate(1,8,3)*nb); 0088 if ~ismember(tmp, idxtmp) 0089 idxtmp(ptr) = tmp; 0090 ptr = ptr + 1; 0091 % idxtmp = [idxtmp; tmp]; 0092 end 0093 end 0094 end 0095 0096 idxtmp = sort(idxtmp); 0097 0098 % in its present form we would: 0099 % map LARGEST generator to SMALLEST selected Zdr 0100 % map SMALLEST generator to LARGEST selected Zdr 0101 0102 % to add some "noise" swap some entries in idxtmp 0103 ngswap = round(0.1*ngp); 0104 for k = 1:ngswap 0105 idx1 = randi(ngp); 0106 idx2 = randi(ngp); 0107 tmp = idxtmp(idx1); 0108 idxtmp(idx1) = idxtmp(idx2); 0109 idxtmp(idx2) = tmp; 0110 end 0111 0112 % the generator buses are idxp sorted in DECREASING order 0113 % idxz are the indices of the buses sorted by Zdr in INCREASING ORDER 0114 % idxtmp is a vector of bus indices that are "roughly" in increasing order 0115 % Therefore, idxz(idxtmp) returns a list of buses whose Zdr is generally in 0116 % increasing magnitude, these are mapped to the generators in decreasing 0117 % order. 0118 nmap(idxp) = idxz(idxtmp); 0119 0120 0121 %% complete permutation for non-gen buses 0122 usedidx = nmap(idxp); 0123 idxtmp = (1:nb)'; 0124 idxtmp = idxtmp(~ismember(idxtmp,usedidx)); %remove used inidices 0125 idxtmp = idxtmp(randperm(length(idxtmp))); 0126 nmap(nmap == 0) = idxtmp; 0127 0128 if length(unique(nmap)) ~= nb 0129 error('sgvm_nodeperm_init: error in generating nmap. Resulting map is not 1-to-1 and onto') 0130 end 0131 %% permute 0132 mpc = sgvm_perform_permute(mpc, nmap, 'nmap');