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

📄 fm_int.m

📁 基于PSAT 软件的多目标最优潮流计算用于中小型电力系统的分析和管理
💻 M
字号:
function  fm_int% FM_INT time domain integration routines:%       1 - Forward Euler%       2 - Trapezoidal Method%% FM_INT%%see also FM_TSTEP, FM_OUT and the Settings structure%%Author:    Federico Milano%Date:      11-Nov-2002%Update:    16-Jan-2003%Update:    27-Feb-2003%Update:    01-Aug-2003%Update:    11-Sep-2003%Version:   1.0.4%%E-mail:    fmilano@thunderbox.uwaterloo.ca%Web-site:  http://thunderbox.uwaterloo.ca/~fmilano%% Copyright (C) 2002-2006 Federico Milanoglobal Fig Settings Snapshot Hdlglobal Bus File DAE Themeglobal SW PV PQ Fault Mn Ltc Syn Exc Oxlglobal Varout Breaker Line Path clpsatif ~autorun('Time Domain Simulation',1), return, endtic% initial messages% -----------------------------------------------------------------------fm_dispif DAE.n == 0 & ~clpsat.init  Settings.ok = 0;  uiwait(fm_choice('No dynamic component is loaded. Continue anyway?',1))  if ~Settings.ok    fm_disp('Time domain simulation aborted.',2)    return  endendfm_disp('Time domain simulation')switch Settings.method case 1,  fm_disp('Implicit Euler integration method') case 2,  fm_disp('Trapezoidal integration method')endfm_disp(['Data file "',Path.data,File.data,'"'])if ~isempty(Path.pert),  fm_disp(['Perturbation file "',Path.pert,File.pert,'"'])endif (strcmp(File.pert,'pert') & strcmp(Path.pert,Path.psat)) | ...      isempty(File.pert)  fm_disp('No perturbation file set.',1)endif Fig.main  hdl = findobj(Fig.main,'Tag','PushClose');  set(hdl,'String','Stop');  set(Fig.main,'UserData',1);endif Settings.plot  if Settings.plottype == 1 & ~DAE.n    Settings.plottype = 2;    fm_disp('Cannot plot state variables (dynamic order = 0).')    fm_disp('Bus voltages will be plotted during the TD simulation.')  end  maxlegend = min(Bus.n,7);  switch Settings.plottype   case 1    maxlegend = min(DAE.n,7);    idx0 = 0;   case 2    idx0 = DAE.n;   case 3    idx0 = DAE.n+Bus.n;   case 4    idx0 = DAE.n+2*Bus.n+2*Syn.n+Exc.n+Oxl;   case 5    idx0 = DAE.n+3*Bus.n+2*Syn.n+Exc.n+Oxl;   case 6    maxlegend = 3;    idx0 = DAE.n+4*Bus.n+2*Syn.n+Exc.n+Oxl;  endend% check settings% ------------------------------------------------------------------iter_max = Settings.dynmit;tol = Settings.dyntol;Dn = 1;if DAE.n, Dn = DAE.n; endidentica = speye(max(Dn,1));if (Fault.n | Breaker.n) & PQ.n & ~Settings.pq2z  if clpsat.init    if clpsat.pq2z, Settings.pq2z = 1; end  else    uiwait(fm_choice(['It is strongly recommended to convert PQ loads ' ...                      'to constant impedances. Do you want to do so?']))    if Settings.ok, Settings.pq2z = 1; end  endendif Settings.pq2z & Settings.init < 2 & PQ.n  idx = find(PQ.gen == 0);  if ~isempty(idx)    % add diagonal shunt admittances    Line.Y = Line.Y + pqshunt(PQ,idx);    PQ = remove(PQ,idx,'force');  endend% set up variables% ----------------------------------------------------------------DAE.t = Settings.t0;fm_call('i');DAE.tn = DAE.f;if isempty(DAE.tn), DAE.tn = 0; endDAE.g = [DAE.gp; DAE.gq];% graphical settings% ----------------------------------------------------------------plot_now = 0;if ~clpsat.init | Fig.main  if Settings.plot    if Fig.plot      figure(Fig.plot);    else      fm_plotfig;    end  elseif Settings.status    fm_bar('open')    fm_simtd('init')    idxo = 0;  else    fm_disp(['t = ',num2str(Settings.t0),' s'],3)    perc = 0;    perc_old = 0;  end  drawnowend% ----------------------------------------------------------------% initializations% ----------------------------------------------------------------t = Settings.t0;k = 1;h = fm_tstep(1,1,0,Settings.t0);if Fault.n ~= 0, fm_fault(0,0), endfm_breaker(0,0)inc = zeros(Dn + 2*Bus.n,1);% output initialization% ----------------------------------------------------------------fm_out(0,0,0);fm_out(2,Settings.t0,k);% time vector of snapshots, faults and breaker events% ----------------------------------------------------------------fixed_times = [];n_snap = length(Snapshot);if n_snap > 1  snap_times = zeros(n_snap-1,1);  for i = 2:n_snap    snap_times(i-1,1) = Snapshot(i).time;  end  fixed_times = [fixed_times; snap_times];endif Fault.n  idx = find(Fault.con(:,5) ~= Fault.con(:,6));  if ~isempty(idx)    fixed_times = [fixed_times; ...                   Fault.con(idx,5)-1e-6; Fault.con(idx,5); ...                   Fault.con(idx,6)-1e-6; Fault.con(idx,6)];  endendif Breaker.n  idx = find(Breaker.con(:,7) ~= Breaker.con(:,8));  if ~isempty(idx)    fixed_times = [fixed_times; ...                   Breaker.con(idx,7)-1e-6; Breaker.con(idx,7); ...                   Breaker.con(idx,8)-1e-6; Breaker.con(idx,8)];  endendfixed_times = sort(fixed_times);% compute max rotor angle differencediff_max = anglediff;% ================================================================% ----------------------------------------------------------------% Main loop% ----------------------------------------------------------------% ================================================================inc = zeros(Dn+2*Bus.n,1);while (t < Settings.tf) & (t + h > t) & ~diff_max  if Fig.main    if ~get(Fig.main,'UserData'), break, end  end  if (t + h > Settings.tf), h = Settings.tf - t; end  actual_time = t + h;  % check not to jump disturbances  index_times = find(fixed_times > t & fixed_times < t+h);  if ~isempty(index_times);    actual_time = min(fixed_times(index_times));    h = actual_time - t;  end  % set global time  DAE.t = actual_time;  % backup of actual variables  if isempty(DAE.x), DAE.x = 0; end  xa = DAE.x;  anga = DAE.a;  Va = DAE.V;  % initialize NR loop  iterazione = 1;  inc(1) = 1;  if isempty(DAE.f), DAE.f = 0; end  fn = DAE.f;  % compute perturbations  if ~isempty(fixed_times)    if ~isempty(find(fixed_times == actual_time))      if Fault.n        fm_fault(1,actual_time)      end      if Breaker.n        fm_breaker(1,actual_time)      end    end  end  if Settings.hostver >= 6    feval(Hdl.pert,actual_time);  else    if ~isempty(Path.pert)      cd(Path.pert)      feval(Hdl.pert,actual_time);      cd(Path.local)    end  end  % Newton-Raphson loop  while max(abs(inc)) > tol    if (iterazione > iter_max), break,  end    drawnow    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 equations    fm_call('i');    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;    % check for islanded buses    if ~isempty(Bus.island)      kkk = Bus.island;      DAE.Jlfv(kkk,:) = 0;      DAE.Jlfv(:,kkk) = 0;      DAE.Jlfv(:,kkk+Bus.n) = 0;      DAE.Jlfv(kkk+Bus.n,:) = 0;      DAE.Jlfv(kkk,kkk) = speye(length(kkk));      DAE.Jlfv(kkk+Bus.n,kkk+Bus.n) = speye(length(kkk));      DAE.g(kkk) = 0;      DAE.g(kkk+Bus.n) = 0;      DAE.V(kkk) = 1e-6;      DAE.a(kkk) = 0;    end    % complete Jacobian matrix DAE.Ac    switch Settings.method     case 1  % Forward Euler      DAE.Ac = [identica - h*DAE.Fx, -h*DAE.Fy; DAE.Gx, DAE.Jlfv];      DAE.tn = DAE.x - xa - h*DAE.f;     case 2  % Trapezoidal Method      DAE.Ac = [identica - h*0.5*DAE.Fx, -h*0.5*DAE.Fy; DAE.Gx, DAE.Jlfv];      DAE.tn = DAE.x - xa - h*0.5*(DAE.f + fn);    end    % non-windup limiters    fm_call('5');    inc = -DAE.Ac\[DAE.tn; DAE.g];    %inc = -umfpack(DAE.Ac,'\',[DAE.tn; DAE.g]);    DAE.x = DAE.x + inc(1:Dn);    DAE.a = DAE.a + inc(1+Dn: Bus.n+Dn);    DAE.V = DAE.V + inc(Dn+Bus.n+1: Dn+2*Bus.n);    iterazione = iterazione + 1;  end  if (iterazione > iter_max)    h = fm_tstep(2,0,iterazione,t);    DAE.x = xa;    DAE.a = anga;    DAE.V = Va;    DAE.f = fn;  else    h = fm_tstep(2,1,iterazione,t);    t = actual_time;    k = k+1;    % extend output stack    if k > length(Varout.t), fm_out(1,t,k); end    % ----------------------------------------------------------------    % ----------------------------------------------------------------    % update output variables and snapshots    % ----------------------------------------------------------------    % ----------------------------------------------------------------    fm_out(2,t,k);    %  plot variables & display iteration status    % ----------------------------------------------------------------    i_plot = 1+k-10*fix(k/10);    perc = (t-Settings.t0)/(Settings.tf-Settings.t0);    if i_plot == 10      fm_disp([' > Simulation time = ',num2str(DAE.t), ...	       ' s (',num2str(round(perc*100)),'%)'])    end    if ~clpsat.init | Fig.main      if Settings.plot        if i_plot == 10          plot(Varout.t(1:k),Varout.vars(1:k,idx0+[1:maxlegend]));          set(gca,'Color',Theme.color11);          xlabel('time (s)')          drawnow        end      elseif Settings.status        idx = (t-Settings.t0)/(Settings.tf-Settings.t0);        fm_bar([idxo,idx])        if i_plot == 10, fm_simtd('update'), end        idxo = idx;      end    end    % fill up snapshots    % ------------------------------------------------------------------    if n_snap > 1      snap_i = find(snap_times == t)+1;      if ~isempty(snap_i)        flag = 1;        DAE.gp = zeros(Bus.n,1);        DAE.gq = zeros(Bus.n,1);        fm_call('1');        Pl = DAE.gp;        Ql = DAE.gq;        P = DAE.glfp;        Q = DAE.glfq;        Snapshot(snap_i).V = DAE.V;        Snapshot(snap_i).ang = DAE.a;        Snapshot(snap_i).x = DAE.x;        Snapshot(snap_i).Y = Line.Y;        Snapshot(snap_i).Pg = P + Pl;        Snapshot(snap_i).Qg = Q + Ql;        Snapshot(snap_i).Pl = DAE.gp;        Snapshot(snap_i).Ql = DAE.gq;        Snapshot(snap_i).vfd = Syn.vf;        Snapshot(snap_i).pmech = Syn.pm;        Snapshot(snap_i).Jlf = DAE.Jlf;        Snapshot(snap_i).Jlfv = DAE.Jlfv;        Snapshot(snap_i).Fx = DAE.Fx;        Snapshot(snap_i).Fy = DAE.Fy;        Snapshot(snap_i).Gx = DAE.Gx;      end    end  end  % compute max rotor angle difference  diff_max = anglediff;endif Settings.status & ~Settings.plot  fm_bar('close')  fm_simtd('update')endif ~DAE.n, DAE.x = []; DAE.f =[]; end% final messages% -----------------------------------------------------------------------if Fig.main  if diff_max & get(Fig.main,'UserData')    fm_disp(['Rotor angle max difference is > ', ...             num2str(Settings.deltadelta), ...             ' deg. Simulation stopped at t = ', ...             num2str(t), ' s'],2);  elseif (t < Settings.tf) & get(Fig.main,'UserData')    fm_disp(['Singularity likely. Simulation stopped at t = ', ...             num2str(t), ' s'],2);  elseif ~get(Fig.main,'UserData')    fm_disp(['Dynamic Simulation interrupted at t = ',num2str(t),' s'],2)  else    fm_disp(['Dynamic Simulation completed in ',num2str(toc),' s']);  endelse  if diff_max    fm_disp(['Rotor angle max difference is > ', ...             num2str(Settings.deltadelta), ...             ' deg. Simulation stopped at t = ', ...             num2str(t), ' s'],2);  elseif (t < Settings.tf)    fm_disp(['Singularity likely. Simulation stopped at t = ', ...             num2str(t), ' s'],2);  else    fm_disp(['Dynamic Simulation completed in ',num2str(toc),' s']);  endend% resize output varibales & final settings% -----------------------------------------------------------------------fm_out(3,t,k);if Settings.beep, beep, endSettings.xlabel = 'time (s)';if Fig.plot, fm_plotfig, end% future simulations do not need LF computationSettings.init = 2;SNB.init = 0;LIB.init = 0;CPF.init = 0;OPF.init = 0;if Fig.main, set(hdl,'String','Close'); endDAE.t = -1; % reset global time% compute delta difference at each step% -----------------------------------------------------------------------function diff_max = anglediffglobal Settings Syn Bus DAEdiff_max = 0;if ~Settings.checkdelta, return, endif ~Syn.n, return, enddelta = DAE.x(Syn.delta);idx = [];for h = 1:length(Bus.island)  idx = [idx; find(Syn.bus == Bus.island(h))];endif ~isempty(idx)  delta(idx) = [];enddelta_diff = abs(delta-min(delta));diff_max = (max(delta_diff)*180/pi) > Settings.deltadelta;

⌨️ 快捷键说明

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