📄 fm_cpf.m
字号:
function lambda_crit = fm_cpf(fun)% FM_CPF continuation power flow routines for computing nose curves% and determining critical points (saddle-node bifurcations)%% [LAMBDAC] = FM_CPF%% LAMBDAC: loading paramter at critical or limit point%%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-2006 Federico Milanofm_varif ~autorun('Continuation Power Flow',0), return, endlambda_crit = [];% Settingsif CPF.ilim ilim = CPF.flow;else ilim = 0;endtype = double(~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; endendif ~PQ.n & ~Demand.n fm_disp('* * * The systems does not present PQ load or Demand data.') fm_disp('* * * Continuation Power Flow analysis interrupted.') returnendstop = 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% ----------------------------------------------------------------------% disable conversion to impedance for PQ loadsPQ = novlim(PQ,'all');nodyn = 0;if 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; 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);else % no dynamic components nodyn = 1; DAE.n = 1; DAE.f = 0; DAE.x = 0; DAE.Fx = 1; DAE.Fy = sparse(1,2*Bus.n); DAE.Gx = sparse(2*Bus.n,1); Flambda = 0; Fk = 0;endPV2PQ = Settings.pv2pq;noDem = 0;noSup = 0;sp = ' * ';Settings.pv2pq = 0;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% if no Demand.con is found, the load direction% is assumed to be the one of the PQ loadif 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 load flow routine may have convergence problems.',2) fm_disp endelse noDem = 1; idx = findpos(PQ); Demand = add(Demand,dmdata(PQ,idx)); PQ = pqzero(PQ,idx);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 = 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.']) if noDem fm_disp('Supply data will be ignored.') noSup = 1; Supply = remove(Supply,[1:Supply.n]); if qlim & type, SW = move2sup(SW); end %SW = move2sup(SW); %PV = move2sup(PV); else 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 end 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 qlim & type, SW = move2sup(SW); end %SW = move2sup(SW); %PV = move2sup(PV);end% 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; endKjac = 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);Kjac(1,DAE.n+Settings.refbus) = 1;kjac(1,DAE.n+Settings.refbus) = 1;% chose a PQ to display the CPF progress in the main windowPQidx = pqdisplay(PQ);if ~PQidx % absence of PQ buses PQidx = pqdisplay(Demand); if ~PQidx if ~perp perp = 1; fm_disp('* * * Switch to perpendicular intersection * * * ') end PQidx = 1; 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 = [];pqlim(PQ,vlim,0,0,0);fm_out(0,0,0)if nodyn DAE.Fx = 1; Varout.idx = Varout.idx+1; endfm_out(1,0,0)% initial Jacobian Gk DAE.Gk = sparse(2*Bus.n,1);if type, Gkcall(Supply), endif type, Gkcall(PV), endGkcall(SW)if Syn.n Fk(pm_idx) = Pm_syn(syn_idx)./Syn.con(syn_idx,18);endDAE.kg = 0;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);fm_lf(2);if noSup Gyreactive(PV)else Gycall(PV);endGyreactive(SW)DAE.Jlfv = [DAE.J11, DAE.J12; DAE.J21, DAE.J22];% First predictor step% ---------------------------------------------------------------Jsign = 1; count_qmin = 0;kqmin = 1;d_lambda = 0;lambda_old = CPF.linit;inc = zeros(DAE.n+2*Bus.n+2,1);Ljac(end) = 1;% critical pointV_crit = DAE.V;a_crit = DAE.a;x_crit = DAE.x;k_crit = kg;l_crit = lambda;while err_max > tol cpfmsg = []; % corrector step % --------------------------------------------------------------- V_old = DAE.V; ang_old = DAE.a; x_old = DAE.x; kg_old = kg; lambda_old = lambda; corrector = 1; if PV.n, inc(DAE.n+Bus.n+PV.bus) = 0; end if SW.n, inc(DAE.n+Bus.n+SW.bus) = 0; end while corrector modinc = norm(inc); if Fig.main if ~get(Fig.main,'UserData'), break, end end iter_corr = 0; err_corr = 1; while err_corr > tol if (iter_corr > 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 component functions and models fm_lf(1); fm_lf(2); gcall(PQ) DAE.Jlf = [DAE.J11, DAE.J12; DAE.J21, DAE.J22]; glambda(Demand,lambda) glambda(Supply,lambda,type*kg) Glcall(Demand) Glcall(Supply) if type, Gkcall(Supply), end Gkcall(Supply) if Syn.n DAE.f(pm_idx) = DAE.f(pm_idx)+ ... (lambda+kg-1)*Pm_syn(syn_idx)./Syn.con(syn_idx,18); Flambda(pm_idx) = Pm_syn(syn_idx)./Syn.con(syn_idx,18); Fk(pm_idx) = Pm_syn(syn_idx)./Syn.con(syn_idx,18); DAE.Jlfv(Settings.refbus,:) = 0; DAE.Jlfv(:,Settings.refbus) = 0; DAE.Jlfv(Settings.refbus,Settings.refbus) = 1; DAE.gp(Settings.refbus) = 0; end if noSup glambda(PV,lambda,type*kg) glambda(SW,lambda,kg) greactive(PV) if type, 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]; if SW.n DAE.Fy(:,Bus.n+SW.bus) = 0; DAE.Gx(Bus.n+SW.bus,:) = 0; DAE.Gl(SW.bus+Bus.n) = 0; end if PV.n DAE.Gl(PV.bus+Bus.n) = 0; DAE.Fy(:,Bus.n+PV.bus) = 0; DAE.Gx(Bus.n+PV.bus,:) = 0; end if perp*iterazione Cinc = sigma_corr*inc; cont_eq = Cinc'*([DAE.x;DAE.a;DAE.V;kg;lambda]- ... [x_old; ang_old; V_old;kg_old; ... lambda_old]-Cinc); inc_corr = -[DAE.Fx, DAE.Fy, Fk, Flambda; DAE.Gx, DAE.Jlfv, ... DAE.Gk, DAE.Gl; Cinc'; Kjac]\[DAE.f; DAE.gp; ... DAE.gq; cont_eq; DAE.a(Settings.refbus)]; else if iterazione cont_eq = DAE.V(PQidx)-sigma_corr*inc(PQidx+DAE.n+Bus.n) - ... V_old(PQidx); else cont_eq = lambda - sigma_corr*d_lambda - lambda_old; end inc_corr = -[DAE.Fx, DAE.Fy, Fk, Flambda; DAE.Gx, DAE.Jlfv, ... DAE.Gk, DAE.Gl; Ljac; Kjac]\[DAE.f; DAE.gp; ... DAE.gq; cont_eq; DAE.a(Settings.refbus)]; end DAE.x = DAE.x + inc_corr(1:DAE.n); DAE.a = DAE.a + inc_corr(1+DAE.n: Bus.n+DAE.n);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -