function [x_traj,y_traj,t,solver_name] = trajectories(x0,y0,time,x,y, ... archive_time,solver, ... abs_tol,rel_tol,path_function) %********************************************************************* % Function to integrate a group of trajectories using a discrete % archive of two-dimensional velocities. %********************************************************************* % Inputs %********************************************************************* % x0 --> vector of particle initial X positions % y0 --> vector of particle initial Y positions % time --> vector of times where particle positions are desired % x --> vector of x values for the archive grid % y --> vector of y values for the archive grid % archive_time --> vector of time values for the archive % solver --> integer specifying solver type % [1=Runge-Kutta, 2=Multi-step NDF] % abs_tol --> absolute tolerance (see help for 'odeset') % rel_tol --> relative tolerance (see help for 'odeset') %********************************************************************* % Outputs %********************************************************************* % x_traj --> 2D array of particle x positions, with dimensions % like x_traj(n_particles,n_time) % % y_traj --> 2D array of particle y positions, with dimensions % like y_traj(n_particles,n_time) % % t --> time values associated with the particle positions % in x_traj and y_traj % % solver_name --> text string containing the name of the solver %********************************************************************* % Setup required: %********************************************************************* % In addition to the supplied input parameters, the gridded archived % (u,v) velocity components must be stored in 3D global variables % named 'u' and 'v', like: % % global u v % % where u = u(ix,jy,ntime) % v = v(ix,jy,ntime) % % ix = number of x grid points % jy = number of y grid points % ntime = number of discrete times in the archive %********************************************************************* % UNITS !!! %********************************************************************* % This function assumes that the length units describing the grid and % particle initial positions (input as [x,y] and [x0,y0]) and the time % units describing both the integration time and archive times (input as % time and archive_time) are consistent with those of the archived % velocities (global 3D arrays u and v). % % The output length and time units are the same as those used for % the inputs. %********************************************************************* global X Y T ip default('solver',1) default('abs_tol',1e-8) default('rel_tol',0) default('path_function','archive_path') abs_tol = max([abs_tol,eps]) ; rel_tol = max([rel_tol,100*eps]) ; abs_tol = 0.01 ; switch solver case 1 solver_routine = 'ode45' ; solver_name = 'Runge-Kutta (ode45)' ; case 2 solver_routine = 'ode15s' ; solver_name = 'Multi-step NDF (ode15s)' ; end t1_string = [datestr(time(1),23),', ',datestr(time(1),15)] ; t2_string = [datestr(time(end),23),', ',datestr(time(end),15)] ; %--------------------------------------------------------------------- % Create 3D grids describing (x,y,time) values for each velocity in % the archive. These grids are passed as global variables to the % path function for use by 'interpn' %--------------------------------------------------------------------- [X,Y,T] = ndgrid(x,y,archive_time) ; %--------------------------------------------------------------------- % Store initial positions in a convenient form %--------------------------------------------------------------------- ntraj = length(x0(:)) ; ip = [x0(:) ; y0(:)] ; %--------------------------------------------------------------------- % Integrate trajectories %--------------------------------------------------------------------- ode_options = odeset('RelTol',rel_tol,'AbsTol',abs_tol,'Stats','on') ; fprintf('\n --> Started integrating %i trajectories\n',ntraj) fprintf('\n Solver: %s',solver_name) fprintf('\n Time interval: %s to %s',t1_string,t2_string) fprintf('\n Time step: %f [%d total steps]',time(2)- ... time(1),length(time)) fprintf('\n Tolerances (ABS,REL): (%8.2d, %8.2d)\n\n',abs_tol,rel_tol) tic [t,pos] = eval(sprintf('%s(''%s'',time,ip,ode_options)', ... solver_routine,path_function)) ; fprintf('\n INTEGRATION FINISHED. [Elapsed time = %i seconds]\n',... round(toc)) %--------------------------------------------------------------------- % Return trajectory positions in x and y arrays %--------------------------------------------------------------------- x_traj = pos(:,1:ntraj)' ; y_traj = pos(:,ntraj+1:2*ntraj)' ; %--------------------------------------------------------------------- % Correct for desired time vectors with only two entries %--------------------------------------------------------------------- if length(time) == 2 t = t([1 end]); x_traj = x_traj(:,[1 end]); y_traj = y_traj(:,[1 end]); end