%{ --------------------------------------------------------------------- Solver for 1D boundary-value problem second-order ODE with Dirichlet boundary conditions Method: unilizes the shooting method + the method of secants (calls 4th-order Runge-Kutta to solve the initial value problem) Demo version for d2y/dx2 = f(x,y,dy/dx) equation AG: Last revision 2 April 2022 To DO later: 1: print if no solution 2: upgrade to Neymann and mixed boundary conditions ---------------------------------------------------------------------- %} clear % Clears command window clc % Clears command history clf % Removes anything in the figure window before simulation tic % set timer for the program f = @f1; % function handle - pass the name of the function to shoot2 n = 51; % number of base points eps = 1.0e-8; % target tolerance x = zeros(1,n); y = zeros(1,n); %* print the header data Date = today('datetime'); fprintf(' Boundary Value Problem \n') fprintf(' Method: Shooting + RK 4th order \n') fprintf(' Date: %s \n', Date) fprintf(' Tolerance %4.2e \n ',eps) fprintf(' x y dy \n') % boundary values x(1) = 0.0; y(1) = 0.0; x(n) = 1.0; y(n) = 1.0; % two assumptions for y'(1) - use dy(1) and dy(2) here only as a storage dy(1) = 1.0; dy(2) = 2.0; % === call the solver [xn,yn,dyn] = shoot2(f,x,y,dy,n,eps); % === % print solutions for i=1:n fprintf(' %8.4f %10.2e %10.2e \n', xn(i), yn(i), dyn(i)) end figure (1) plot(xn,yn,'r-o') title('Boundary Value Problem'); xlabel('x'); ylabel('y(x)'); grid; timeE = ceil(toc); fprintf('\n time elapsed = %4i sec \n',timeE) function [f1] = f1(x,y,dy) %{ !------------------------------------------ the second derivative - use original ODE d2y/dx2 = f(x,y,dy) ------------------------------------------ %} %f1 = -5.0*dy-4.0*y*y+exp(x); %f1 = -4.0*dy - 6.25*y + exp(x); f1 = 0-4.0*x*y*dy-(6.25*y*y*sin(x*y))*y+exp(x); end function [x,y,dy] = shoot2(f,x,y,dy,n,eps) %{ !====================================================================== ! Solution of the boundary-value second-order 1D ODE ! d2y/dx2 = f(x,y,dy/dx) with Dirichlet boundary conditions ! y(xmin) = ..., and y(xmax) = ... ! Method: unilizes the shooting method based on the method of secants ! (calls 4th-order Runge-Kutta to solve the initial value problem) ! written by: Alex Godunov (last revision - 9 October 2009) !---------------------------------------------------------------------- ! input ... ! f(x,y,dy) - function d2y/dx2 (supplied by a user) ! x(1), x(n) - boundary points ! y(1), y(n) - boundary values (Dirichlet boundary conditions) ! dy(1),dy(2) - two guesses for y'(x(1)) ! n - number of grid points ! eps - tolerance (abs value) ! output ... ! y(i) and dy(i) solutions at points x(i) (i=1,...,n) ! note: dy corresponds to y' (the first derivative) !====================================================================== %} it=101; % max number of iterations g = zeros(1,it); c = zeros(1,it); % g(it) - array of dy(it) values [iterative improvement] % c(it) - array of y(n) values [iterative solutions for g(it)] % first guesses for g(it) g(1) = dy(1); g(2) = dy(2); %! remember the second boundary condition %! since y(n) recalculated for each new g(i) yn = y(n); % generate base points x(i) from x(1), x(n) and n dx = (x(n)-x(1))/(n-1); for i=2:n x(i) = x(i-1)+dx; end % shooting iterations (for the first two - we use assumed values of dy(1)) for k=1:it dy(1) = g(k); [y,dy] = rk4_2d(f,x,y,dy,n); % solves initial value ODE on n-base points c(k) = y(n); if abs(yn-c(k)) < eps break end if k >= 2 g(k+1)=g(k)-(c(k)-yn)*(g(k)-g(k-1))/(c(k)-c(k-1)); end end fprintf(' Interations %3i \n',k-2) end % function shoot2 function [y,dy] = rk4_2d(f,x,y,dy,n) %{ ================================================================ Solution of the second-order 1D ODE (Initial-value problem) method: Runge-Kutta 4th-order written by: Alex Godunov (last revision March 2021) ---------------------------------------------------------------- input ... f(x,y,dy)- function from d2y/dx2=f(x,y,dy) (supplied by a user) x(i) - array of x base point (n points) y(1) - initial value for y(1) dy(1) - initial value for y'(1) output ... y(i) - solutions for y in n points dy(i) - solutions for y' in n points ================================================= %} for k=2:n h = x(k)-x(k-1); k11 = h*dy(k-1); k12 = h*f(x(k-1),y(k-1),dy(k-1)); k21 = h*(dy(k-1)+k12/2.0); k22 = h*f(x(k-1)+h/2.0, y(k-1)+k11/2.0, dy(k-1)+k12/2.0); k31 = h*(dy(k-1)+k22/2.0); k32 = h*f(x(k-1)+h/2.0, y(k-1)+k21/2.0, dy(k-1)+k22/2.0); k41 = h*(dy(k-1)+k32); k42 = h*f(x(k-1)+h,y(k-1)+k31,dy(k-1)+k32); y(k) = y(k-1) + (k11 + 2.0*(k21+k31) + k41)/6.0; dy(k) = dy(k-1)+ (k12 + 2.0*(k22+k32) + k42)/6.0; end end % function rk4_2d