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

📄 fm_cpf.m

📁 电力系统的psat
💻 M
📖 第 1 页 / 共 3 页
字号:
function [lambda_crit, dl_dp] = fm_cpf(fun)% FM_CPF continuation power flow routines for computing nose curves%        and determining critical points (saddle-node bifurcations)%% [LAMBDAC] = FM_CPF% [LAMBDAC,DL_DP] = FM_CPF%%       LAMBDAC: loading paramter at critical or limit point%%                                            d lambda |%       DL_DP: sensitivity coefficients      -------- |%                                               d p   |c%%see also CPF structure and FM_CPFFIG%%Author:    Federico Milano%Date:      11-Nov-2002%Update:    16-Sep-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_var%global etaRif ~autorun('Continuation Power Flow'), return, end%  Settingsif CPF.ilim  ilim = CPF.flow;else  ilim = 0;endtype = ~CPF.sbus;if type & SW.n == 1 & Supply.n == 1  if Supply.bus ~= SW.bus    fm_disp(' * * ')    fm_disp('Only one Supply found. Single slack bus model will be used.')    type = 0;  endendstop = CPF.type - 1;vlim = CPF.vlim;qlim = CPF.qlim;perp = ~(CPF.method - 1);if strcmp(fun,'atc') | strcmp(fun,'gams')  one = 1;else  one = 0;end%if PV.n+SW.n == 1%  type = 0;%endif CPF.show  fm_disp  if type    fm_disp('Continuation Power Flow - Distribuited Slack Bus')  else    fm_disp('Continuation Power Flow - Single Slack Bus')  end  fm_disp(['Data file "',Path.data,File.data,'"'])  fm_disp  if perp    fm_disp('Corrector Method:         Perpendicular Intersection')  else    fm_disp('Corrector Method:         Local Parametrization')  end  if vlim    fm_disp('Check Voltage Limits:     Yes')  else    fm_disp('Check Voltage Limits:     No')  end  if qlim    fm_disp('Check Generator Q Limits: Yes')  else    fm_disp('Check Generator Q Limits: No')  end  if ilim    fm_disp('Check Flow Limits:        Yes')  else    fm_disp('Check Flow Limits:        No')  end  fm_dispend% Initializations of vectors and matrices of state and algebraic% functions and variables% ----------------------------------------------------------------------%warning off% make a copy of PQ, PV and SW structuresPQold = PQ;PVold = PV;SWold = SW;% disable conversion to impedance for PQ loadsPQ.con(:,8) = 0;nodyn = 0;ksw = 0;kpv = 0;if SW.n, ksw = SW.con(:,11); endif PV.n, kpv = PV.con(:,10); end% fix unconsistent participation factorsif sum(kpv) == 0,  kpv = ones(PV.n,1);endif Syn.n  Pm_syn = Syn.pm;  pm_idx = Syn.omega;  syn_idx = [1:Syn.n]';  if Tg.n    pm_idx(Tg.syn) = [];    syn_idx(Tg.syn) = [];  endend% initialization of the state vector and Jacobian maticesif DAE.n > 0  DAE.f = ones(DAE.n,1);  % state variable time derivatives  DAE.x = ones(DAE.n,1);  % state variables  fm_xfirst;  if Settings.octave    DAE.Fx = zeros(DAE.n,DAE.n);   % Dx(f)    DAE.Fy = zeros(DAE.n,2*Bus.n); % Dy(f)    DAE.Gx = zeros(2*Bus.n,DAE.n); % Dx(g)    Flambda = zeros(DAE.n,1);    Fk = zeros(DAE.n,1);  else    DAE.Fx = sparse(DAE.n,DAE.n);   % Dx(f)    DAE.Fy = sparse(DAE.n,2*Bus.n); % Dy(f)    DAE.Gx = sparse(2*Bus.n,DAE.n); % Dx(g)    Flambda = sparse(DAE.n,1);    Fk = sparse(DAE.n,1);  endelse  % no dynamic components  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);  end  Flambda = 0;  Fk = 0;endnoDem = 0;noSup = 0;sp = ' * ';if ilim  tps = Line.con(:,11).*exp(jay*Line.con(:,12)*pi/180);  r = Line.con(:,8);  rx = Line.con(:,9);  chrg = Line.con(:,10)/2;  z = r + jay*rx;  y = 1./z;  g = real(y);  b = imag(y);  Imax = Line.con(:,12+ilim);  switch ilim   case 1, fw = 'I ';   case 2, fw = 'P ';   case 3, fw = 'S ';  end  Imax(find(Imax <= 0)) = 99999;  % no limit for undefined limitend% the slack bus active power is the power injection obtained% by the power flowfor i = 1:SW.n,  k = SW.bus(i);  length(Snapshot.V); % do not remove this line!!!                       % It fixes an Octave bug  if ~isempty(Snapshot(1).Pg)    pg = Snapshot(1).Pg;    if pg(k) ~= 0      SW.con(i,10) = pg(k);    end  endend% if no Demand.con is found, the load direction% is assumed to be the one of the PQ loadif Demand.n  no_dpq = find(Demand.con(:,3) == 0 & Demand.con(:,4) == 0);  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 load flow routine may have convergence problems.',2)    fm_disp  endelse  noDem = 1;  Ppos = find(PQ.con(:,4) > 0);  Demand.con = zeros(length(Ppos),14);  Demand.n = length(Ppos);  Demand.bus = PQ.bus(Ppos);  Demand.con(:,[1 2 3 4]) = PQ.con(Ppos,[1 2 4 5]);  Demand.con(:,14) = 1;  PQ.con(Ppos,[4 5]) = 0;end% if no Supply.con is found, the load direction% is assumed to be the one of the PV or the SW generatorif Supply.n  no_sp = find(Supply.con(:,3) == 0);  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;  if PV.n    Ppos = find(PV.con(:,4) > 0);    Supply.con = zeros(length(Ppos),14);    Supply.n = length(Ppos);    Supply.bus = PV.bus(Ppos);    Supply.con(:,[1 2 3]) = PV.con(Ppos,[1 2 4]);    Supply.con(:,14) = 1;    PV.con(Ppos,4) = 0;  end  if SW.n    Ppos = find(SW.con(:,10) ~= 0);    Supply.n = Supply.n+length(Ppos);    Supply.bus = [Supply.bus; SW.bus(Ppos)];    Supply.con(end+[1:length(Ppos)],[1 2 3]) = SW.con(Ppos,[1 2 10]);    Supply.con((end-length(Ppos)+1):end,14) = 1;    SW.con(Ppos,10) = 0;  endend% Newton-Raphson routine settingsiter_max = Settings.lfmit;iterazione = 0;tol =  CPF.tolc;tolf = CPF.tolf;tolv = CPF.tolv;err_max = tol+1;proceed = 1;sigma_corr = 1;if DAE.n == 0, DAE.n = 1; endif Settings.octave  Kjac = zeros(1,2*Bus.n+DAE.n+2);  Ljac = zeros(1,2*Bus.n+DAE.n+2);  kjac = zeros(1,2*Bus.n+DAE.n+1);else  Kjac = sparse(1,2*Bus.n+DAE.n+2);  Ljac = sparse(1,2*Bus.n+DAE.n+2);  kjac = sparse(1,2*Bus.n+DAE.n+1);endif Supply.n  Kjac(1,DAE.n+SW.bus) = 1;else  Kjac(1,end-1) = 1;endif Supply.n  kjac(DAE.n+SW.bus) = 1;else  kjac(1,end) = 1;end% A PQ bus is chosen for visualizing the CPF progress in the main windowPQidx = 0;for i = 1:PQ.n  a = find(PQ.bus(i) == PV.bus);  b = find(PQ.bus(i) == SW.bus);  if isempty(a) & isempty(b)    PQidx = PQ.bus(i);    break  endendif ~PQidx % absence of PQ buses  for i = 1:Demand.n    a = find(Demand.bus(i) == PV.bus);    b = find(Demand.bus(i) == SW.bus);    if isempty(a) & isempty(b)      PQidx = Demand.bus(i);      break    end  end  if ~PQidx    if ~perp      perp = 1;       fm_disp('* * * Switch to perpendicular intersection * * * ')          end    PQidx = 1;  endend% chose bus to be monitored during CPF analysisPQidxplot = PQidx;% distributed slack bus coefficientsksu = zeros(Supply.n,1);for i = 1:PV.n  idx = find(Supply.bus == PV.bus(i));  if idx    ksu(idx) = PV.con(i,10);  endendfor i = 1:SW.n  idx = find(Supply.bus == SW.bus(i));  if idx    ksu(idx) = SW.con(i,11);  endend% *********************************************************************% Continuation Power Flow Routine% *********************************************************************ticfm_status('cpf','init',12,{'m'},{'-'},{Theme.color11},[0 1.2])l_vect = [];lambda = CPF.linit;lambda_crit = CPF.linit;kg = 0;lambda_old = -1;Jsign = 0;Jsign_old = 0;Sflag = 1;ksign = 1;Qmax_idx = [];Qmin_idx = [];Vmax_idx = [];Vmin_idx = [];Iij_idx = [];Iji_idx = [];Iij = ones(Line.n,1);Iji = ones(Line.n,1);Qswmax_idx = [];Qswmin_idx = [];PQVmax = ones(PQ.n,1);PQVmin = ones(PQ.n,1);fm_out(0,0,0)fm_out(1,0,0)while err_max > tol  cpfmsg = [];  if iterazione >= CPF.nump & ~strcmp(fun,'gams')    fm_disp([sp,'Reached maximum number of points.'])    break  end  if Fig.main    if ~get(Fig.main,'UserData'), break, end  end  if isempty(Line.Y)

⌨️ 快捷键说明

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