📄 fm_int.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: Federico.Milano@uclm.es%Web-site: http://www.uclm.es/area/gsee/Web/Federico%% Copyright (C) 2002-2008 Federico Milanoglobal Fig Settings Snapshot Hdlglobal Bus File DAE Theme OMIBglobal SW PV PQ Fault Motglobal 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+DAE.m; case 5 idx0 = DAE.n+DAE.m+Bus.n; case 6 maxlegend = 3; idx0 = DAE.n+DAE.m+2*Bus.n; 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(['Convert (recommended) PQ loads to constant impedances?'])) if Settings.ok, Settings.pq2z = 1; end endend% convert PQ loads to shunt admittances (if required)PQ = pqshunt(PQ);% set up variables% ----------------------------------------------------------------DAE.t = Settings.t0;fm_call('i');DAE.tn = DAE.f;if isempty(DAE.tn), DAE.tn = 0; end% 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);inc = zeros(Dn+DAE.m,1);callpert = 1;% get initial network connectivityfm_flows('connectivity','verbose');% output initializationfm_out(0,0,0);fm_out(2,Settings.t0,k);% time vector of snapshots, faults and breaker eventsfixed_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];endfixed_times = [fixed_times; gettimes(Fault); ... gettimes(Breaker); gettimes(Mot)];fixed_times = sort(fixed_times);% compute max rotor angle differencediff_max = anglediff;% ================================================================% ----------------------------------------------------------------% Main loop% ----------------------------------------------------------------% ================================================================inc = zeros(Dn+DAE.m,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; ya = DAE.y; % initialize NR loop iterazione = 1; inc(1) = 1; if isempty(DAE.f), DAE.f = 0; end fn = DAE.f; % applying faults, breaker interventions and perturbations if ~isempty(fixed_times) if ~isempty(find(fixed_times == actual_time)) Fault = intervention(Fault,actual_time); Breaker = intervention(Breaker,actual_time); end end if callpert try 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 catch fm_disp('* * Something wrong in the perturbation file:') fm_disp(lasterr) fm_disp('* * The perturbation file will be discarded.') callpert = 0; 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 % DAE equations fm_call('i'); % complete Jacobian matrix DAE.Ac switch Settings.method case 1 % Forward Euler DAE.Ac = [identica - h*DAE.Fx, -h*DAE.Fy; DAE.Gx, DAE.Gy]; 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.Gy]; 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.y = DAE.y + inc(1+Dn: DAE.m+Dn); iterazione = iterazione + 1; end if (iterazione > iter_max) h = fm_tstep(2,0,iterazione,t); DAE.x = xa; DAE.y = ya; 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, snapshots and network visualisation % ---------------------------------------------------------------- % ---------------------------------------------------------------- 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; fm_snap('assignsnap',snap_i); 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 DAE SW OMIBdiff_max = 0;if ~Settings.checkdelta, return, endif ~Syn.n, return, enddelta = DAE.x(Syn.delta);[idx,ia,ib] = intersect(Bus.island,getbus(Syn));if ~isempty(idx), delta(ib) = []; endif isscalar(delta) delta = [delta; DAE.y(SW.refbus)];enddelta_diff = abs(delta-min(delta));diff_max = (max(delta_diff)*180/pi) > Settings.deltadelta;if diff_max, return, end% check transient stability%fm_omib%if abs(OMIB.margin) > 1e-2% fm_disp(['* * Transient stability margin: ',num2str(OMIB.margin)])%end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -