POSTPROC_MAXLOADLIM Performs some post processing on the results returned by the ACOPF run in MATPOWER. RESULTS = POSTPROC_MAXLOADLIM(RESULTS,DIR_MLL) transforms the dispatchable loads back to normal loads and parse the results in the struct RESULTS to provide contextual information on the maximum loadability point found in the direction of load increase defined by DIR_MLL. It returns the updated struct RESULTS.
0001 function results = postproc_maxloadlim(results,dir_mll) 0002 % POSTPROC_MAXLOADLIM Performs some post processing on the results returned 0003 % by the ACOPF run in MATPOWER. 0004 % RESULTS = POSTPROC_MAXLOADLIM(RESULTS,DIR_MLL) transforms the dispatchable 0005 % loads back to normal loads and parse the results in the struct RESULTS 0006 % to provide contextual information on the maximum loadability point 0007 % found in the direction of load increase defined by DIR_MLL. It returns 0008 % the updated struct RESULTS. 0009 0010 % MATPOWER 0011 % Copyright (c) 2015-2016, Power Systems Engineering Research Center (PSERC) 0012 % by Camille Hamon 0013 % 0014 % This file is part of MATPOWER. 0015 % Covered by the 3-clause BSD License (see LICENSE file for details). 0016 % See http://www.pserc.cornell.edu/matpower/ for more info. 0017 0018 define_constants; 0019 0020 % Transforming the dispatchable gen back to loads 0021 idx_gen_load_disp = isload(results.gen); 0022 idx_bus_load_disp = results.gen(idx_gen_load_disp,GEN_BUS); 0023 results.bus(idx_bus_load_disp ,[PD QD]) = -results.gen(idx_gen_load_disp,[PG QG]); 0024 results.gen(idx_gen_load_disp,:) = []; 0025 results.gencost(idx_gen_load_disp,:) = []; 0026 % Removing the shadow prices corresponding to dispatchable loads 0027 results.var.mu.u.Qg(idx_gen_load_disp) = []; 0028 % If all gens at bus have non zero reactive power shadow prices, this bus 0029 % is PQ 0030 for bb = 1:size(results.bus,1) 0031 gen_list_at_bb = results.gen(:,GEN_BUS) == bb; 0032 if all(results.var.mu.u.Qg(gen_list_at_bb)>0) 0033 results.bus(bb,BUS_TYPE) = PQ; 0034 end 0035 end 0036 0037 % Create a new field for the stability margin in load increase 0038 results.stab_marg = results.var.val.alpha; 0039 % Create a new field for the stability margin in gen change 0040 if isfield(results.var.val,'beta') 0041 results.gen_stab_marg = results.var.val.beta; 0042 end 0043 0044 % Remove the cost for the printpf function to consider the results as load 0045 % flow results. 0046 results.f = []; 0047 % Direction defined over all buses (not only over nonzero loads) 0048 results.dir_mll = dir_mll; 0049 0050 % Determining the type of bifurcation (SNB or SLL) 0051 % SLL is characterized by having both reactive power limit and voltage 0052 % limit binding at one generator 0053 shadow_price_Qg = results.var.mu.u.Qg; 0054 shadow_price_Vm = results.var.mu.u.Vm; 0055 % Map the shadow price of bus voltage magnitude to generators 0056 shadow_price_Vg = shadow_price_Vm(results.gen(:,GEN_BUS)); 0057 idx_bus_sll = shadow_price_Qg & shadow_price_Vg; 0058 if sum(idx_bus_sll) > 0 0059 results.bif.short_name = 'LIB'; 0060 results.bif.full_name = 'limit-induced bifurcation'; 0061 results.bif.gen_sll = find(idx_bus_sll); 0062 else 0063 results.bif.short_name = 'SNB'; 0064 results.bif.full_name = 'saddle-node bifurcation'; 0065 end 0066 % Building the sets of gens that reached their Q lims and of gens that did 0067 % not 0068 gen_a = shadow_price_Vm(results.gen(:,GEN_BUS))~= 0; 0069 gen_b = shadow_price_Qg ~= 0; 0070 results.bif.gen_a = gen_a; 0071 results.bif.gen_b = gen_b;