%====================================== % Solver for a system of n first order % Ordinary Differential Equations % (initial value problem) % % Can be used for solving a system of n/2 second order ODE % % Demo version for 2D projectile motion % % AG: Last revision November 2020 %====================================== clear % Clears command window clc % Clears command history clf % Removes anything in the figure window before simulation. % global constatns and variables global g rad Pi D yatm g = 9.80; % free fall acceleration m/s^2 rad = 0.017533; % degree to radians Pi = 3.1415926; % Pi % initialize arrays n = 4; % number of equations xf = zeros(1,n); xi = zeros(1,n); %* print the header and initial data Date = today('datetime'); fprintf(' 4-nd order a system of n ODEs \n') fprintf(' Method: Runge-Kutta 4th order \n') fprintf(' Date %s \n', Date) % === projectile === m = 0.011; % mass of a projectile rho = 1.25; % air density C = 0.02; % aerodynamic coefficient r = 0.005; % radius of projectile A = Pi*r^2; % cross sectional area D = 0.5*C*rho*A/m; % drag coefficient yatm = 10000; % for varaible air density % === Initial data for motion === ti = 0.0; % initial value for variable t v0 = 320.0; % initial speed angle = 45.0; % initial angle (degrees) x0 = 0.0; % initial position in x y0 = 0.0; % initial position in y % preparing for calculations xi(1) = x0; xi(2) = y0; xi(3) = v0*cos(angle*rad); % initial speed in x direction xi(4) = v0*sin(angle*rad); % initial speed in y direction energy= m*g*xi(2) + 0.5*m*(xi(3)*xi(3)+xi(4)*xi(4)); % initial energy % estimate distance and time if no air resistance and ven ground % or y0 = yf Range = v0^2 * sin(2*angle*rad) /g; TimeofFlight = 2*v0*sin(angle*rad) /g; Ymax = v0^2 * (sin(angle*rad))^2 /(2*g); %print initial data and analytic results fprintf(' v0 = %9.2f m/s\n',v0) fprintf(' angle = %9.2f deg\n',angle) fprintf(' estimated time = %9.2f sec\n',TimeofFlight) fprintf(' estimated ymax = %9.2f meters\n',Ymax) fprintf(' estimated range = %9.2f meters\n',Range) % printing ithe header fprintf... (' t x(t) y(t) vx(t) vy(t) energy \n') % step size and max time dt = 0.1; tmax = 300.0; %tmax = TimeofFlight; % integrate from ti till tmax %preparation to plot results ip = 1; tp(ip) = ti; xp(ip) = xi(1); yp(ip) = xi(2); %analytic solution xa(ip) = xi(1); ya(ip) = xi(2); %=== integration of ODE while (ti < tmax) fprintf('%10.2e %10.2e %10.2e %10.2e %10.2e %10.2e\n',... ti, xi(1), xi(2), xi(3), xi(4), energy); if xi(2) < 0.0, break, end % break if hitting ground y=0 tf = ti + dt; % =================================*/ xf = RK4n(n, ti, tf, xi); % =================================*/ % prepare for the next step ti = tf; for i = 1: n xi(i) = xf(i); end % arrys for figures ip=ip+1; tp(ip) = ti; xp(ip) = xi(1); yp(ip) = xi(2); % analytic solution xa(ip) = xa(1) + v0*cos(angle*rad)*tf; ya(ip) = ya(1) + v0*sin(angle*rad)*tf - 0.5*g*tf^2; % end arrays for fugures energy = m*g*xi(2) + 0.5*m*((xi(3))^2+ (xi(4))^2); end %end of while % Linear interpolation for the time of flight tFlight = tp(ip) - yp(ip)*(tp(ip)-tp(ip-1))/(yp(ip)-yp(ip-1)); xRange = xp(ip) - yp(ip)*(xp(ip)-xp(ip-1))/(yp(ip)-yp(ip-1)); fprintf('\n tFlight = %9.3f seconds\n',tFlight) fprintf(' xRange = %9.3f meters\n',xRange) plot(xp,yp,'r-o',xa,ya,'b-o') xlabel('distance') ylabel('height') title ('2D Projectile Motion') %Range = Range*1.1; %Ymax = Ymax *1.1; %plot(xp,yp,'r',xa,ya,'b') %xlim([0 Range]) %ylim([0 Ymax]) %xlabel('distance') %ylabel('height') %title ('2D Projectile Motion') %end of program function [dx] = dnx(n, t, x) % function for 2D projectile motion global g rad Pi D yatm Dc = D * exp((-1.0*x(2)/yatm)); v = sqrt( (x(3))^2+(x(4))^2 ); % /* first order */ dx(1) = x(3); dx(2) = x(4); % /* second order */ dx(3) = 0.0 - Dc * x(3)*v; dx(4) = (-1.0)*g - Dc * x(4)*v; end %*========================================================== % RK4n Solution of a system of n first-order ODE % method: Runge-Kutta 4th-order % written by: Alex Godunov % last revision: November, 2020 % ---------------------------------------------------------- % call ... (supplied by a user) % dx = dnx(n, t, x) functions dx/dt where dx and x are arrays size n % input ... % n - number of first order equations % ti - initial time % tf - solution time % xi - initial values (array size n) % output ... % xf - solutions (array size n) % % ==========================================================*/ function [xf] = RK4n(n,ti, tf, xi) % reserve arrays xf = zeros(1,n); k1 = zeros(1,4); k2 = zeros(1,4); k3 = zeros(1,4); k4 = zeros(1,4); % calculations h = tf-ti; t = ti; % k1 dx=dnx(n, t, xi); for j = 1: n k1(j) = h*dx(j); x(j) = xi(j) + k1(j)/2.0; end % //k2 dx = dnx(n, t+h/2.0, x); for j = 1: n k2(j) = h*dx(j); x(j) = xi(j) + k2(j)/2.0; end %//k3 dx = dnx(n, t+h/2.0, x); for j = 1: n k3(j) = h*dx(j); x(j) = xi(j) + k3(j); end %//k4 and result dx = dnx(n, t+h, x); for j = 1: n k4(j) = h*dx(j); xf(j) = xi(j) + k1(j)/6.0+k2(j)/3.0+k3(j)/3.0+k4(j)/6.0; end end % end of RK4n