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

📄 fm_spf.m

📁 电力系统的psat
💻 M
字号:
function fm_spf% FM_SPF solve standard power flow by means of the NR method%       and fast decoupled power flow (XB and BX variations)%       with either a single or distributed slack bus model.%% FM_SPF%%see the properties of the Settings structure for options.%%Author:    Federico Milano%Date:      11-Nov-2002%Update:    09-Jul-2003%Version:   1.0.1%%E-mail:    fmilano@thunderbox.uwaterloo.ca%Web-site:  http://thunderbox.uwaterloo.ca/~fmilano%% Copyright (C) 2002-2005 Federico Milano%% This toolbox is free software; you can redistribute it and/or modify% it under the terms of the GNU General Public License as published by% the Free Software Foundation; either version 2.0 of the License, or% (at your option) any later version.%% This toolbox is distributed in the hope that it will be useful, but% WITHOUT ANY WARRANTY; without even the implied warranty of% MERCHANDABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU% General Public License for more details.%% You should have received a copy of the GNU General Public License% along with this toolbox; if not, write to the Free Software% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,% USA.fm_varfm_dispfm_disp('Newton-Raphson Method for Power Flow Computation')if Settings.show  fm_disp(['Data file "',Path.data,File.data,'"'])endnodyn = 0;% these computations are needed only the first time the power flow is runif ~Settings.init  check = fm_ncomp;     % bus type initialization  if ~check, return, end  % report components parameters to system bases  if Settings.conv, fm_base, end  fm_y                  % create Admittance Matrix                        % create the FM_CALL FUNCTION  if Settings.show, fm_disp('Writing file "fm_call" ...',1), end  fm_wcall;  Settings.refbus = SW.bus(1); % reference bus (for phase angle)  fm_dynlf; % indicization of components used in power flow computationsend% memory allocation for equations and Jacobiansif (DAE.n~=0)  DAE.f = ones(DAE.n,1);  % differential equations  DAE.x = ones(DAE.n,1);  % state variables  fm_xfirst;  if Settings.octave    DAE.Fx = zeros(DAE.n,DAE.n);   % df/dx    DAE.Fy = zeros(DAE.n,2*Bus.n); % df/dy    DAE.Gx = zeros(2*Bus.n,DAE.n); % dg/dx  else    DAE.Fx = sparse(DAE.n,DAE.n);   % df/dx    DAE.Fy = sparse(DAE.n,2*Bus.n); % df/dy    DAE.Gx = sparse(2*Bus.n,DAE.n); % dg/dx  endelse  % no dynamic elements  nodyn = 1;  DAE.n = 1;  DAE.f = 0;  DAE.x = 0;  DAE.Fx = 1;  if Settings.octave    DAE.Fy = zeros(1,2*Bus.n);    DAE.Gx = zeros(2*Bus.n,1);  else    DAE.Fy = sparse(1,2*Bus.n);    DAE.Gx = sparse(2*Bus.n,1);  endend% check PF solver methodFDPF = Settings.pfsolver;if FDPF > 1  if Mn.n, mn = sum(~Mn.con(:,8));  else, mn = 0; end  if Pl.n, pl = sum(~Pl.con(:,11)); else, pl = 0; end  ncload = mn + pl + Lines.n + (~nodyn) + Tcsc.n;  if ncload | Settings.distrsw,    FDPF = 1; % force using standard NR method  else    fm_b    no_sw = 1:Bus.n;    no_sw(SW.bus) = [];    no_g = 1:Bus.n;    no_g([SW.bus; PV.bus]) = [];    Bp = Line.Bp(no_sw,no_sw);    Bpp = Line.Bpp(no_g,no_g);    [Lp, Up, Pp] = lu(Bp);    [Lpp, Upp, Ppp] = lu(Bpp);  endendswitch FDPF case 1, fm_disp('PF solver: Newton-Raphson method') case 2, fm_disp('PF solver: XB fast decoupled power flow method') case 3, fm_disp('PF solver: BX fast decoupled power flow method')endif Settings.distrsw  Jkg = sparse(DAE.n+2*Bus.n,1);  Jrow = sparse(1,DAE.n+SW.bus,1,1,DAE.n+2*Bus.n+1);  DAE.kg = 0;  idx = find(SW.con(:,10) == 0);  if length(idx) > 1    fm_disp('More than one slack bus with zero power indication found.')    fm_disp('Single slack bus model will be used')    Setting.distrsw = 0;  end  if idx    SW.con(1,10) = sum(PQ.con(:,4))-sum(PV.con(:,4));    fm_disp('Slack bus with zero power direction found.')    fm_disp('P_slack = sum(P_load)-sum(P_gen) will be used.')    fm_disp('Only PQ loads and PV generators are used.')    fm_disp('If there are convergence problems, use the single slack bus model.')  end  if SW.n,    ksw = SW.con(:,11);    Jkg(DAE.n+SW.bus) = -ksw.*SW.con(:,10);  end  if PV.n,    kpv = PV.con(:,10);    Jkg(DAE.n+PV.bus) = -PV.con(:,10).*PV.con(:,4);  endendswitch Settings.distrsw case 1  fm_disp('Distributed slack bus model') case 0  fm_disp('Single slack bus model')endif FDPF > 1, fm_call('fdpf'), enditer_max = Settings.lfmit;if iter_max < 2, iter_max = 2; enditeration = 0;tol = Settings.lftol;err_max = tol+1;% Graphical settingsfm_status('pf','init',iter_max,{'r'},{'-'},{Theme.color11})%  Newton-Raphson routinet0 = clock;while (err_max > tol) & (iteration <= iter_max)  if Fig.main    if ~get(Fig.main,'UserData'), break, end  end  if FDPF == 1   % Standard NR technique    if Settings.octave      DAE.gp = zeros(Bus.n,1);      DAE.gq = zeros(Bus.n,1);      DAE.J11 = zeros(Bus.n,Bus.n);      DAE.J21 = zeros(Bus.n,Bus.n);      DAE.J12 = zeros(Bus.n,Bus.n);      DAE.J22 = zeros(Bus.n,Bus.n);    else      DAE.gp = sparse(Bus.n,1);      DAE.gq = sparse(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    % component calls    if Settings.distrsw      fm_call('kgpf');      if SW.n        DAE.g(SW.bus) = DAE.g(SW.bus)-(1+DAE.kg*ksw).*SW.con(:,10);        DAE.g(Bus.n+SW.bus)=0;      end      Gbus = Bus.n+[SW.bus;PV.bus];      DAE.Jlfv(Gbus,:) = 0;      DAE.Jlfv(:,Gbus) = 0;      DAE.Jlfv(:,SW.bus) = 0;      if Settings.octave        DAE.Jlfv(Gbus,Gbus) = eye(PV.n+SW.n);      else        DAE.Jlfv(Gbus,Gbus) = speye(PV.n+SW.n);      end      DAE.Fy(:,SW.bus) = 0;      DAE.Gx(SW.bus,:) = 0;      if nodyn, DAE.Fx = 1; end      inc = -[[DAE.Fx, DAE.Fy; DAE.Gx, DAE.Jlfv],Jkg;Jrow]\[DAE.f; DAE.g; 0];      DAE.x = DAE.x + inc(1:DAE.n);      DAE.a = DAE.a + inc(1+DAE.n:Bus.n+DAE.n);      DAE.V = DAE.V + inc(DAE.n+Bus.n+1:DAE.n+2*Bus.n);      DAE.kg = DAE.kg + inc(end);    else      fm_call('l');      % complete Jacobian matrix      DAE.Fy(:,SW.bus) = 0;      DAE.Gx(SW.bus,:) = 0;      DAE.Fy(:,Bus.n+SW.bus) = 0;      DAE.Gx(Bus.n+SW.bus,:) = 0;      DAE.Fy(:,Bus.n+PV.bus) = 0;      DAE.Gx(Bus.n+PV.bus,:) = 0;      if nodyn, DAE.Fx = 1; end      inc = -[DAE.Fx, DAE.Fy; DAE.Gx, DAE.Jlfv]\[DAE.f; DAE.g];      DAE.x = DAE.x + inc(1:DAE.n);      DAE.a = DAE.a + inc(1+DAE.n:Bus.n+DAE.n);      DAE.V = DAE.V + inc(DAE.n+Bus.n+1:DAE.n+2*Bus.n);    end  else % Fast Decoupled Power Flow    % P-theta    da = -(Up\(Lp\(Pp*DAE.gp(no_sw))));    DAE.a(no_sw) = DAE.a(no_sw) + da;    Vc = DAE.V.*exp(j*DAE.a);    fm_call('fdpf')    normP = norm(DAE.gp,inf);    normQ = norm(DAE.gq,inf);    if normP < tol & normQ < tol, break, end    % Q-V    dV = -(Upp\(Lpp\(Ppp*DAE.gq(no_g))));    DAE.V(no_g) = DAE.V(no_g)+dV;    Vc = DAE.V.*exp(j*DAE.a);    fm_call('fdpf')    normP = norm(DAE.gp,inf);    normQ = norm(DAE.gq,inf);    if normP < tol & normQ < tol, break, end    inc = [normP; normQ];    % recompute Bpp if some PV bus has been switched to PQ bus    if Settings.pv2pq & strmatch('Switch',History.text{end})      fm_disp('Recomputing Bpp matrix for FDPF')      no_g = 1:Bus.n;      no_g([SW.bus; PV.bus]) = [];      Bpp = Line.Bpp(no_g,no_g);      [Lpp, Upp, Ppp] = lu(Bpp);    end  end  iteration = iteration + 1;  err_max = max(abs(inc));  fm_status('pf','update',[iteration, err_max],iteration)  if Settings.show    if err_max == Inf, err_max = 1e3; end     fm_disp(['Iteration = ', num2str(iteration), ...             '     Maximum Convergency Error = ', ...             num2str(err_max)],1)  endendSettings.lftime = etime(clock,t0);Settings.iter = iteration;if iteration > iter_max  fm_disp(['Reached Maximum number of iteration for NR Routine without ' ...           'Convergence'],2)end% Total power injection and adsorption at network buses% restore PV buses switched to PQ busesif Settings.pv2pq & PV.pq.n  PV.n = PV.n + PV.pq.n;  PV.bus = [PV.bus; PV.pq.bus];  PV.pq.con(:,5) = DAE.V(PV.pq.bus);  PV.con = [PV.con; PV.pq.con(:,[1:end-1])];  PV.pq.n = 0;  PV.pq.bus = [];  PV.pq.con = [];end% Pl and Ql computation (shunts only)DAE.gp = zeros(Bus.n,1);DAE.gq = zeros(Bus.n,1);fm_call('pq');Bus.Pl = DAE.gp;Bus.Ql = DAE.gq;%Pg and Qg computationif 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;% reset of global variables DAE.gp and DAE.gq%DAE.gp = zeros(Bus.n,1);%DAE.gq = zeros(Bus.n,1);% memory allocation for dynamic variables & state variables indicizationif nodyn == 1; DAE.x = []; DAE.f = []; DAE.n = 0; enddynordold = DAE.n;DAE.npf = DAE.n;fm_dynidx;if (DAE.n~=0)  DAE.f = [DAE.f; ones(DAE.n-dynordold,1)];  % differential equations  DAE.x = [DAE.x; ones(DAE.n-dynordold,1)];  % state variables  if Settings.octave    DAE.Fx = zeros(DAE.n,DAE.n); % state Jacobian df/dx    DAE.Fy = zeros(DAE.n,2*Bus.n); % state Jacobian df/dy    DAE.Gx = zeros(2*Bus.n,DAE.n); % algebraic Jacobian dg/dx  else    DAE.Fx = sparse(DAE.n,DAE.n); % state Jacobian df/dx    DAE.Fy = sparse(DAE.n,2*Bus.n); % state Jacobian df/dy    DAE.Gx = sparse(2*Bus.n,DAE.n); % algebraic Jacobian dg/dx  endend%  build cell arrays of variable namesif (Bus.n>0), fm_idx(1), endif (DAE.n>0), fm_idx(2), endif (Settings.vs == 1), fm_idx(3), end% initializations of state variables and componentsif Settings.static  fm_disp('* * * Dynamic components are not initialized * * *')endSettings.init = 1;fm_synitfm_excinfm_call('0');% start up of induction machinesif Mot.n > 0, fm_mot(5), end% power flow result visualizationfm_disp(['Power Flow completed in ',num2str(Settings.lftime),' s'])if Settings.showlf == 1 | Fig.stat  fm_stat;else  if Settings.beep, beep, endend% initialization of all equations & JacobiansDAE.gp = zeros(Bus.n,1);DAE.gq = zeros(Bus.n,1);if Settings.octave  DAE.J11 = zeros(Bus.n,Bus.n);  DAE.J21 = zeros(Bus.n,Bus.n);  DAE.J12 = zeros(Bus.n,Bus.n);  DAE.J22 = zeros(Bus.n,Bus.n);else  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);endfm_call('i');% build structure "Snapshot"if isempty(Settings.t0) & Fig.main  hdl = findobj(Fig.main,'Tag','EditText3');  Settings.t0 = str2num(get(hdl,'String'));endif ~Settings.locksnap  Snapshot = struct('name','Power Flow Results', ...                    'time',Settings.t0, ...                    'V',DAE.V, ...                    'ang',DAE.a, ...                    'x',DAE.x,...                    'Y',Line.Y, ...                    'Pg',Bus.Pg, ...                    'Qg',Bus.Qg, ...                    'Pl',Bus.Pl, ...                    'Ql',Bus.Ql, ...                    'vfd',Syn.vf, ...                    'pmech',Syn.pm, ...                    'Jlf',DAE.Jlf, ...                    'Jlfv',DAE.Jlfv, ...                    'Fx',DAE.Fx, ...                    'Fy',DAE.Fy, ...                    'Gx',DAE.Gx, ...                    'Ploss',sum(DAE.glfp), ...                    'Qloss',sum(DAE.glfq), ...                    'it',1);endfm_status('pf','close')LIB.selbus = min(LIB.selbus,Bus.n);if Fig.lib,  set(findobj(Fig.lib,'Tag','Listbox1'), ...      'String',Varname.bus, ...      'Value',LIB.selbus);end

⌨️ 快捷键说明

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