1

Suppose we have $v_t + v_x = 0$ with initial condition $v(x,0) = \sin^2 \pi(x-1)$ for $x \in [1,2]$. The leap frog scheme is given by

$$ u_k^{n+1} = u_{k}^{n-1} - \alpha ( u_{k+1}^n - u_{k-1}^n ) $$

where $\alpha = \Delta t / \Delta x $.

When we discretize our domain, say in the interval $x=[0,3]$, we observe that

$$ u_k^0 = (u_0^0, u_1^0, u_2^0,....,u_N^0 ) $$

is given by our initial condition. However, say we want to implement this in matlab, for example, if we want to get $u^1$ we have

$$ u_k^1 = u_k^{-1} - \alpha ( u_{k+1}^0 - u_{k-1}^0 ) $$

We run into difficulties because we dont know what the list $u_k^{-1} = (u_0^{-1},u_1^{-1},..., u_N^{-1} ) $ is ? I suppose this corresponds to a second initial contidion which is below the x-axis, one time step below so we need an initial condition of the form $v(x,-\Delta t)$. How can we obtain such initial condition?

%%%%%Initializing variables
F = @(x) sin(pi*(x-1)).^2 .* (1<=x).*(x<=2);
xmin=0;
xmax=8;
N=16;
dx=(xmax-xmin)/N;
t=0;
tmax=4;
dt=0.75*dx;
tsteps=tmax/dt;

%%%%%%grid & initial condition
x=xmin - dx: dx: xmax+dx;

u0=F(x);
u=u0;


%%%second initial condition: find u_k^1

for i=1:N+2
u1(i)=u0(i)-(dt/dx)*(u0(i+1)-u0(i));
end

unp0 = u0
unp1 = u1; %%%%Initialize next u, u(n+1)
figure;
plot(x,u0);


%%%Loop thru time

 for n=1:tsteps

     u(1)=u(3);
     u(N+3)=u(N+1);

     for i=2:N+2
         unp1(i) = unp0(i)-(dt/dx)*(u(i+1)-u(i-1));
     end

    t=t+dt;
    u=unp1;
    exact=F(x-t);
    plot(x,u,'bo-',x,exact,'r-')

 end
James
  • 3,997
  • As with every multi-step method you need one or multiple starter steps that are provided by a different method. Try the Euler methods or the Crank-Nicolson scheme (trapezoidal in time). Be aware that the midpoint method is only weakly stable. – Lutz Lehmann Feb 09 '19 at 21:03
  • but if I want to implement it with leapfrog, how would i obtain the points $u^{-1}$? Use the $v(x,0)$ perhaps? – James Feb 09 '19 at 21:18
  • You need $u_k^1$. One way to compute these is, as I said, a trapezoidal scheme, $$\frac{u_k^1-u_k^0}{Δt}=-\frac12\left(\frac{u_{k+1}^0-u_{k-1}^0}{2Δx}+\frac{u_{k+1}^1-u_{k-1}^1}{2Δx}\right).$$ This now is a tri-diagonal system for the values $u_k^1$. – Lutz Lehmann Feb 09 '19 at 21:45
  • Or, I can use

    $$ u_k^1 = u_k^0 - (\Delta t / \Delta x) (u_{k+1}^0 - u_k^0 ) $$

    The euler method as you suggested. So, just to clarify doubts, With this two inital conditions $u_k^0, u_k^1$, I should be able to get the program running.

    – James Feb 09 '19 at 23:10
  • Yes, you can do that. But the midpoint multistep method (central Euler method, two-step Nyström method) is rather sensitive to errors in the first step, they propagate exponentially growing and with alternating sign, see for instance https://math.stackexchange.com/a/3067889/115115. – Lutz Lehmann Feb 09 '19 at 23:38
  • It's very nice post. Thanks for the link!. Ok, I will implement it in matlab and see how this scheme does – James Feb 09 '19 at 23:55
  • @LutzL I have updated my question with the matlab code, but it isnt working. am I implementing it correctly? – James Feb 10 '19 at 01:02

1 Answers1

4

You need to cycle all of the arrays in the loop, at the moment you leave unp0 with the original value of u0. Also, as usual, avoid loops that you can express as vector operations, the execution will be faster.

 for n=1:tsteps
     u2 = u0;
     u2(2:N+2) -=  (dt/dx)*(u1(3:N+3)-u1(1:N+1))
     u2(1)=u2(3);
     u2(N+3)=u2(N+1);

    t=t+dt;
    u0=u1; u1=u2;
    exact=F(x-t);
    plot(x,u1,'bo-',x,exact,'r-')

 end
Lutz Lehmann
  • 126,666
  • I run it, but it blows up at $dt = 0.75 dx $. This isn't supposed to blow up at this relation. I thought as long as $|dt/dx|<1$ we should have stability. thanks for your reply – James Feb 10 '19 at 16:06
  • 16 points just are not enough. You have an event of size 1, you need at least about 10 points in that length to capture the shape correctly in all shifts. – Lutz Lehmann Feb 10 '19 at 19:57