% InhomPoisson_Shooting_Example.m % % example code demonstrating the use of the shooting method on the Poisson % equation % problem: u''(x) = f, % a <= x <= b % u(a) = 0, u(v) = 0 % % in the present test problem, % a = 0, b = 1, f = x(x-1) % solution: x^4/12-x^3/6+x/1 % % the boundary value problem is solved as an initial value problem with the % introduction of new variables % u1 := u % u2 := u' % with these, the new eigenvalue problem is % u1'(x) = u2(x) % u2'(x) = f(x); % with initial condition: u1(0) = 0, u2(0) = xd; % this can be interpreted as a nonlinear equation: the input is xd, the % output is u1(b), and we look for a xd for which u1(b) = 0 % % the shooting method is similar in the case of the flow stability % equations, except in the case of flow stability, the full solution is known at one end, and alpha % (comlex wavenumber) us tuned so that the boundary condition is satisfied % at the other end %% clear all close all clc %% parameters % domain boundaries a = 0; b = 1; domain = [a,b]; % options for the ODE solver: absolute and relative error tolerances odeopt = odeset('Reltol',1e-12,'Abstol',1e-12); % calculating source term (f) on an equidistant grid on the domain with 100 gridpoints xvec = linspace(a,b,100).'; fvec = (xvec-1).*xvec; %% function handles % with these additional parameters can be passed when calling a function % the first one is a handle for an ordinary differential equation, which % can be passed to an ODE solver, which is a build-in MATLAB function for solving an Ordinary Differential Equation % the second one is a nonlinear equation, which is the solution of the % Poisson equation as an initial value problem % % the parameters of the ODE function handle are % the independent variable (x) and % the depedent (u(x)) variables % here we have two additional parameters which are 'burned in' here % these are the grid for the source term and the source term at the gridpoints % for details see the function below fhandle = @(x,u) PoissonODE(x,u,xvec,fvec); % % % the parameters of the nonlinear equation function are the boundary value problem formulated as an % ODE (fhandle), the the domain of the computation (domain) % the only remaining input is x0 ftosolve = @(xd) Poissonshooting(fhandle,domain,xd); % initial guess for the nonlinear problem xd0 = 10; % solution of the nonlinear problem - the unknown first derivative xder = fsolve(ftosolve,xd0); % recalculating the solution of the Poisson equation with the known proper % initial condition [x,sol] = ode45(fhandle,[a,b],[0;xder],odeopt); % plotting solution figure; plot(x,sol(:,1)); hold on; uexact = x.^4 / 12 - x.^3 /6 + x/12; plot(x,uexact,'-*'); xlabel('x'); ylabel('u(x)'); % plotting error % note that the error increases linearly, as the solution error accumulates err = abs(uexact - sol(:,1)); figure; plot(x,err,'-*'); xlabel('x'); ylabel('abs(u_{exact}-u)'); %% functions for the nonlinear problem and the ODE function u_b = Poissonshooting(fh,domain,xd0) % function formulating the nonlinear problem of solving the boundary value % problem as an initial value problem % % parameters: % fh: function handle for the ODE solver % domain: domain for ODE solution % xd0: the derivative, which we are % % in order to solve with fsolve, the inputs fh and domain need to be added % before % this can be done by creating a function handle % ode option object for ODE tolerances odeopt = odeset('Reltol',1e-12,'Abstol',1e-12); % solution of the ODE with solver ode45 % parameters: function handle, solution domain, initial condition, ode option object % initial condition: the function is zero, the derivative is the input [~,x_] = ode45(fh,domain,[0;xd0],odeopt); % the output is the boundary condition at the other end: u(b) = 0 u_b = x_(end,1); end function dudt = PoissonODE(x,u,xvec,fvec) % ODE function for the Poisson-equation % u'(1) = u(2); % u'(2) = f % parameters: % x: independent variable % u: dependent variable - 2x1 column vector % xvec: grid points for source term % fvec: source term at grid points % % in order to use with ode solver (e.g. ode45), the inputs xvec and fvec need to be added before % this can be done by creating a function handle dudt(2,1) = interp1(xvec,fvec,x,'pchip'); % interpolation dudt(1,1) = u(2); end