⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fm_snb.m

📁 基于PSAT 软件的多目标最优潮流计算用于中小型电力系统的分析和管理
💻 M
字号:
function fm_snb% FM_SNB compute Saddle-node Bifurcation%        by means of a Direct Method%% FM_SNB%%System Equations:%       g(y,kg,lambda) = 0   ->  operating point%       dg/dy'*ro = 0        ->  transversality condition%       |ro| - 1 = 0         ->  non-trivial condition%%       where:  g = load flow equations%               y = [theta; V]%               ro = right eigenvector%               lambda = loading parameter%% Options:%          SNB.slack:  1  ->  distribuited slack bus%                      0  ->  single slack bus%% Output:  SNB.lambda: saddle node value of lambda%          SNB.dldp:   sensitivity factors%%Author:    Federico Milano%Date:      11-Nov-2002%Update:    11-Feb-2003%Version:   1.0.2%%E-mail:    fmilano@thunderbox.uwaterloo.ca%Web-site:  http://thunderbox.uwaterloo.ca/~fmilano%% Copyright (C) 2002-2006 Federico Milanofm_varif ~autorun('SNB Direct Method',0), return, end% check for continuation power flow solution% lambda the maximum lambda obtained with the CPF analysis% or 1e-3 if no CPF analysis has been performed.if ~CPF.init & ~clpsat.init  Settings.ok = 0;  uiwait(fm_choice(['It is strongly recommended running a CPF to get ' ...      'a solution close to the SNB point. Run CPF?'],1))  if Settings.ok    cpf_old = CPF;    CPF.vlim = 0;    CPF.ilim = 0;    CPF.qlim = 0;    CPF.type = 2;    CPF.linit = 0;    CPF.show = 0;    CPF.nump = 200;    CPF.step = 0.25;    fm_cpf('snb');    lambda = CPF.lambda;    kg = CPF.kg;    CPF = cpf_old;  else    lambda = 1;    kg = 1e-3;  endelse  lambda = CPF.lambda;  kg = CPF.kg;enddistr = SNB.slack;% check for loaded componentsif Mn.n, mn = sum(~Mn.con(:,8));  else, mn = 0; endif Pl.n, pl = sum(~Pl.con(:,11)); else, pl = 0; endncload = mn + pl + Lines.n;if ncload | DAE.n  fm_disp('only PV, PQ and SW buses are allowed for SNB computations.')  returnendfm_dispif distr  fm_disp('Direct Method for SNB Computation - Distribuited Slack Bus')else  fm_disp('Direct Method for SNB Computation - Single Slack Bus')endfm_disp('                                  - Right Eigenvector')fm_dispfm_disp(['Data file "',Path.data,File.data,'"'])fm_dispPQ = novlim(PQ,'all');noDem = 0;noSup = 0;bus_gen = [SW.bus; PV.bus];n_gen = PV.n+SW.n;Settings.pv2pq = 0;% if no Demand.con is used, the load power direction% is assumed to be the one defined by the PQ loadsif Demand.n  no_dpq = findzero(Demand);  if ~isempty(no_dpq),    fm_disp    for i = 1:length(no_dpq)      fm_disp(['No power direction found in "Demand.con" for Bus ', ...               Varname.bus{Demand.bus(no_dpq(i))}])    end    fm_disp('Continuation power flow routine may have convergence problems.',2)    fm_disp  endelse  noDem = 1;end% if no Supply.con is used, the generator power direction% is assumed to be equal to the PV oneif Supply.n  no_sp = findzero(Supply);  if ~isempty(no_sp),    fm_disp    if length(no_sp) == Supply.n      fm_disp(['No power directions found in "Supply.con" for all buses.'])      fm_disp('Remove "Supply" components or set power directions.')      fm_disp('Continuation power flow interrupted',2)      if CPF.show, set(Fig.main,'Pointer','arrow'); end      return    else      for i = 1:length(no_sp)        fm_disp(['No power direction found in "Supply.con" for Bus ', ...                 Varname.bus{Supply.bus(no_sp(i))}])      end      fm_disp('Continuation power flow routine may have convergence problems.',2)      fm_disp    end  endelse  noSup = 1;end% vector and matrix initializationDAE.Gl = sparse(2*Bus.n,1);DAE.Gk = sparse(2*Bus.n,1);Nrow = sparse(1,2*Bus.n+1);Ncol = sparse(2*Bus.n,1);Nmat = sparse(2*Bus.n+1,2*Bus.n+1);Kjac = sparse(1,2*Bus.n+1);Kjac(1,SW.bus) = 1;if ~distr, SW = setgamma(SW); endif noDem  Glcall(PQ);else  Glcall(Demand);endGlcall(Supply);if distr, Gkcall(Supply); endif noSup  Glcall(PV);  if distr, Gkcall(PV); end  Glcall(SW);endGkcall(SW);if SW.n, DAE.Gl(SW.bus+Bus.n) = 0; endif PV.n, DAE.Gl(PV.bus+Bus.n) = 0; end[Vect,D] = eig(full(DAE.Jlfv));diagD = diag(D);idx = find(diagD == 1);if ~isempty(idx)  diagD(idx) = 1e6;end[val,idx] = min(abs(diagD));Vect = inv(Vect.');M = real(Vect(1:Bus.n,idx))+1e-4;W = real(Vect(Bus.n+1:2*Bus.n,idx))+1e-4;Z = 0;iter_max = Settings.lfmit;iteration = 0;tol = Settings.lftol;g1 = ones(2*Bus.n,1);if DAE.n == 0, dynordold = 0; DAE.n = 1; end%  Direct Methodticfm_status('snb','init',iter_max,{'r'},{'-'},{'g'})a_old = DAE.a;v_old = DAE.V;l_old = lambda;k_old = kg;m_old = M;w_old = W;z_old = Z;err_max = tol+1;err_max_old = err_max + 1;robust = 1;while err_max > tol  if (iteration > iter_max), break, end  if Fig.main    if ~get(Fig.main,'UserData'), break, end  end  if isempty(Line.Y)    DAE.gp = zeros(Bus.n,1);    DAE.gq = zeros(Bus.n,1);    DAE.J11 = sparse(Bus.n,Bus.n);    DAE.J21 = sparse(Bus.n,Bus.n);    DAE.J12 = sparse(Bus.n,Bus.n);    DAE.J22 = sparse(Bus.n,Bus.n);  end  %DAE.Gl = sparse(2*Bus.n,1);  %DAE.Gk = sparse(2*Bus.n,1);  % call components functions and models  fm_lf(1);  fm_lf(2);  if noDem    glambda(PQ,lambda);    %Glcall(PQ);  else    gcall(PQ);    glambda(Demand,lambda);    %Glcall(Demand);  end  glambda(Supply,lambda,distr*kg);  %Glcall(Supply);  %if distr, Gkcall(Supply); end  if noSup    glambda(PV,lambda,distr*kg)    glambda(SW,lambda,kg)    greactive(PV)    %if distr, Gkcall(PV), end    %Glcall(PV)    Gyreactive(PV)    %Glcall(SW)  else    gcall(PV);    Gycall(PV);    glambda(SW,1,kg)  end  %Gkcall(SW)  greactive(SW)  Gyreactive(SW)    DAE.Jlfv = [DAE.J11, DAE.J12; DAE.J21, DAE.J22];  % non-trivial condition ||w|| = 1  norm_eq = norm([M', W', Z]);  Vjac = [M', W', Z]/norm_eq;  gy = [DAE.Jlfv, DAE.Gk; Kjac]'*[M; W; Z];  % complete Jacobian matrix  AC = [[fm_hessian([M;W]),Ncol;Nrow],[DAE.Jlfv,DAE.Gk; Kjac]',[Ncol;0]; ...        [DAE.Jlfv,DAE.Gk;Kjac],Nmat,[DAE.Gl;0];Nrow,Vjac,0];    inc = -robust*(AC\[gy; DAE.gp; DAE.gq; DAE.a(SW.bus);norm_eq-1]);  err_max = max(abs(inc));  if err_max > 2*err_max_old & iteration    DAE.a  = a_old;    DAE.V  = v_old;    lambda = l_old;    kg = k_old;    M  = m_old;    W  = w_old;    Z  = z_old;    robust = 0.5*robust;    if robust < tol, iteration = iter_max+1; break, end  else    a_old = DAE.a;    v_old = DAE.V;    l_old = lambda;    k_old = kg;    m_old = M;    w_old = W;    z_old = Z;    DAE.a = DAE.a + inc(1:Bus.n);         idx = Bus.n;    DAE.V = DAE.V + inc(idx+1:idx+Bus.n); idx = idx + Bus.n;    kg = kg + inc(idx+1);                 idx = idx + 1;    M = M + inc(idx+1:idx+Bus.n);         idx = idx + Bus.n;    W = W + inc(idx+1:idx+Bus.n);         idx = idx + Bus.n;    Z = Z + inc(idx+1);                   idx = idx + 1;    lambda = lambda + inc(idx+1);    err_max_old = err_max;    iteration = iteration + 1;    if Settings.show      fm_disp(['iteration = ', int2str(iteration), ...               ';   lambda = ',num2str(lambda), ...               '   kg = ',num2str(kg), ...               '   err = ',num2str(err_max)])    end    fm_status('snb','update',[iteration, err_max],iteration)  endend% ===========================================================================%                                  d lambda |% sensistivity coefficients        -------- |%                                     d p   |c% ===========================================================================W = [M; W; Z];d1 = 2*Bus.n+1;d2 = Supply.n;d3 = Demand.n;Sbus = double(Supply.bus);Dbus = Demand.bus;if noDem  d3 = PQ.n;  Dbus = double(PQ.bus);endif noSup  d2 = SW.n + PV.n;  Sbus = double([PV.bus;SW.bus]);endDpfc = sparse(d1,d2+d3);Dpfc = Dpfc + sparse(Sbus,[1:d2],-(lambda+kg),d1,d2+d3);Dpfc = Dpfc + sparse(Dbus,d2+[1:d3],lambda,d1,d2+d3);dl_dp = full(-W'*Dpfc/(W'*[DAE.Gl;0]))';% Update Pg, Qg, Pl and Ql% ===========================================================================DAE.gp = zeros(Bus.n,1);DAE.gq = zeros(Bus.n,1);fm_call('pq');glambda(Demand,lambda)Bus.Pl = DAE.gp;Bus.Ql = DAE.gq;if Line.n, fm_lf(1), endDAE.gp = zeros(Bus.n,1);DAE.gq = zeros(Bus.n,1);fm_call('1');Bus.Pg = DAE.gp + DAE.glfp;Bus.Qg = DAE.gq + DAE.glfq;% Display results% ===========================================================================serv_test{1,1} = ['lambda = ',fvar(lambda,8)];serv_test{2,1} = ['kg = ',fvar(kg,8)];serv_test{3,1} = '  ';if d2  serv_test = [serv_test;strcat('d lambda / d Ps_',Varname.bus(Sbus), ...                                '=',num2str(dl_dp(1:d2)))];endserv_test{end+1,1} = ' ';if d3  serv_test = [serv_test;strcat('d lambda / d Pd_',Varname.bus(Dbus), ...                                '=',num2str(dl_dp(d2+[1:d3])))];endfm_dispDAE.n = dynordold;Settings.iter = iteration;Settings.lftime = toc;if robust < tol  fm_disp('Increment step below threshold. Bad initial point. SNB routine stopped.',2)elseif iteration >= iter_max  fm_disp(['Direct Method for SNB did not converge.'],2)else  fm_disp(['Direct Method for SNB completed in ',num2str(toc),' s'])  if Settings.showlf == 1, fm_stat(serv_test), endendSNB.lambda = lambda;SNB.dldp = dl_dp;SNB.bus = strvcat(strcat('s_',num2str(Supply.bus)), strcat('d_',num2str(Demand.bus)));% restore original data% ===========================================================================fm_status('snb','close')PQ = resetvlim(PQ);PQ = pqreset(PQ,'all');SW = restore(SW);SNB.init = 1;LIB.init = 0;CPF.init = 0;OPF.init = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -