Skip to article frontmatterSkip to article content

Numerical PDE I: Finite Difference

Introduction

Partial Differential Equations (PDEs) are fundamental tools in the mathematical modeling of various physical phenomena. Unlike Ordinary Differential Equations (ODEs), which involve functions of a single variable and their derivatives, PDEs involve functions of multiple variables and their partial derivatives. This distinction makes PDEs particularly powerful in describing systems where changes occur in more than one dimension, such as in space and time.

A PDE is an equation that relates the partial derivatives of a multivariable function. In general form, a PDE can be written as:

F(x1,x2,,xn,u,ux1,ux2,,kux1k1x2k2xnkn)=0\begin{align} F\left(x_1, x_2, \ldots, x_n, u, \frac{\partial u}{\partial x_1}, \frac{\partial u}{\partial x_2}, \ldots, \frac{\partial^k u}{\partial x_1^{k_1}\partial x_2^{k_2} \ldots \partial x_n^{k_n}}\right) = 0 \end{align}

where u=u(x1,x2,,xn)u = u(x_1, x_2, \ldots, x_n) is the unknown function, and u/xi\partial u/\partial x_i denotes the partial derivatives of uu with respect to the variables xix_i.

PDEs are essential in modeling continuous systems where the state of the system depends on multiple variables. They appear in various fields such as physics, engineering, finance, and biology, describing phenomena like heat conduction, wave propagation, fluid dynamics, and quantum mechanics.

Definition and Significance in Modeling Continuous Systems

PDEs provide a framework for formulating problems involving functions of several variables and their rates of change. They are indispensable in describing the behavior of physical systems where spatial and temporal variations are intrinsic. Examples include:

  • Advection Equation: Models a quantity, e.g., density, moves with velocity cc:

    ut+cu=0.\begin{align} \frac{\partial u}{\partial t} + c \nabla u = 0. \end{align}
  • Heat Equation: Models the distribution of heat (or temperature) in a given region over time.

    ut=α2u.\begin{align} \frac{\partial u}{\partial t} = \alpha \nabla^2 u. \end{align}
  • Wave Equation: Describes the propagation of waves, such as sound or electromagnetic waves, through a medium.

    2ut2=c22u\begin{align} \frac{\partial^2 u}{\partial t^2} = c^2 \nabla^2 u \end{align}
  • Laplace’s Equation: Represents steady-state solutions where the system does not change over time, such as electric potential in a region devoid of charge.

    2u=0\begin{align} \nabla^2 u = 0 \end{align}

The ability to model such diverse phenomena underscores the versatility and importance of PDEs in scientific and engineering disciplines.

Finite Difference Methods (FDM)

Solving PDEs numerically is essential for modeling complex physical systems that lack closed-form analytical solutions. Among the various numerical methods available, Finite Difference Methods (FDM) are particularly popular due to their simplicity and ease of implementation. They approximate the derivatives in PDEs by using difference on a discretized grid. This approach transforms continuous PDEs into discrete algebraic equations that can be solved iteratively. FDM is widely used in engineering and scientific computations due to its straightforward application to regular grids and its compatibility with existing numerical solvers.

Forward Time Centered Space

The Forward Time Centered Space (FTCS) scheme is one of the simplest explicit finite difference methods used to solve time-dependent PDEs. It approximates the time derivative using a forward difference and the spatial derivatives using centered differences.

Consider the linear advection equation that models the transport of a quantity uu with constant speed cc:

ut+cux=0\begin{align} \frac{\partial u}{\partial t} + c \frac{\partial u}{\partial x} = 0 \end{align}

Let uinu_i^n denote the numerical approximation of uu at spatial index ii and time level nn. The FTCS scheme discretizes the advection equation as follows:

uin+1uinΔt+cui+1nui1n2Δx=0\begin{align} \frac{u_i^{n+1} - u_i^n}{\Delta t} + c \frac{u_{i+1}^n - u_{i-1}^n}{2 \Delta x} = 0 \end{align}

Solving for uin+1u_i^{n+1}:

uin+1=uincΔt2Δx(ui+1nui1n)\begin{align} u_i^{n+1} = u_i^n - \frac{c \Delta t}{2 \Delta x} \left( u_{i+1}^n - u_{i-1}^n \right) \end{align}

This explicit update rule allows the computation of the solution at the next time step based on the current and neighboring spatial points.

Here is a simple python implementation:

# Parameters

c  = 1.0    # advection speed
l  = 1.0    # domain size
dt = 0.005  # time step

nx = 100    # number of spatial points
nt = 200    # number of time steps
import numpy as np

X, dx = np.linspace(0, l, nx, endpoint=False, retstep=True)  # spatial grid
U0    = np.sin(2*np.pi * X)  # initial condition
# Forward Time Centered Space (FTCS) scheme

def FTCS(c, U0, dx, dt, n):
    sigma = c * dt / dx
    U = [U0]
    for _ in range(n):
        U0 = U[-1]
        U1 = U0 - sigma * (np.roll(U0,-1) - np.roll(U0,1)) / 2
        U.append(U1)
    return np.array(U)
U     = np.sin(2*np.pi * (X - c*dt*nt)) # analytical solution
UFTCS = FTCS(c, U0, dx, dt, nt)         # numerical solution

Let’s now plot the result! After t=dtnt=1t = dt n_t = 1, the solution should match the initial condition exactly.

from matplotlib import pyplot as plt

plt.plot(X, U0,              label='Initial Condition')
plt.plot(X, U, ':',          label='Exact Solution')
plt.plot(X, UFTCS[-1], '.-', label='FTCS Scheme')
plt.xlabel('x')
plt.ylabel('u')
plt.legend()

However, the numerical solution is oscillating. This looks like a numerical artifact. Let’s inspect it with a movie.

from matplotlib.animation import ArtistAnimation
from IPython.display import HTML
from tqdm import tqdm

def animate(X, U):
    fig, ax = plt.subplots(1,1)
    ax.set_xlabel('x')
    ax.set_ylabel('y')

    frames = []
    for n in tqdm(range(len(U))):
        f = ax.plot(X, U[n], 'C0.-', animated=True)
        frames.append(f)
        plt.close()
    
    return ArtistAnimation(fig, frames, interval=50)
anim = animate(X, UFTCS)

HTML(anim.to_html5_video())  # display animation
# anim.save('FTCS.mp4')        # save animation

The oscillation grows slowly as the solution evolve. This looks like numerical instability that we discussed in ODE integrator.

# HANDSON: change `c`, `dt`, `dx`, or other parameters to observe how
#          the numerical solution changes.
# HANDSON: change the initial condition to, e.g., a boxcar function,
#          and observe how the numerical solution changes

To understand the oscillation, we will perform a stability analysis.

Von Neumann Stability Analysis

Von Neumann stability analysis is a mathematical technique used to assess the stability of finite difference schemes applied to (linear) PDEs. This method involves decomposing the numerical solution into Fourier modes and analyzing the growth or decay of these modes over time. If all Fourier modes remain bounded, the numerical scheme is considered stable. Otherwise, the scheme is unstable and may produce erroneous results.

To perform von Neumann stability analysis, we assume a solution of the form:

uin=Gneikxi\begin{align} u_i^n = G^n e^{ikx_i} \end{align}

where:

  • uinu_i^n is the numerical approximation of uu at spatial index ii and time level nn.

  • GG is the amplification factor (recall our ODE stability analysis).

  • kk is the wave number.

  • xi=iΔxx_i = i \Delta x is the spatial position of the ii-th grid point.

The goal is to determine whether the magnitude of the amplification factor G|G| remains less than or equal to 1 for all possible wave numbers kk. If G1|G| \leq 1 for all kk, the numerical scheme is stable.

Now, consider the FTCS scheme applied to the linear advection equation

ut+cux=0,\begin{align} \frac{\partial u}{\partial t} + c \frac{\partial u}{\partial x} = 0, \end{align}

where the FTCS update rule reads

uin+1=uincΔt2Δx(ui+1nui1n).\begin{align} u_i^{n+1} = u_i^n - \frac{c\Delta t}{2\Delta x} \left(u_{i+1}^n - u_{i-1}^n\right). \end{align}

Assumed a single Fourier mode solution,

uin=Gneikxi.\begin{align} u_i^n = G^n e^{ikx_i}. \end{align}

Substituting it into the FTCS update rule,

Geikxi=eikxicΔt2Δx(eikxi+1eikxi1).\begin{align} G e^{ikx_i} = e^{ikx_i} - \frac{c\Delta t}{2\Delta x} \left(e^{ikx_{i+1}} - e^{ikx_{i-1}}\right). \end{align}

Simplify using xi±1=xi±Δxx_{i \pm 1} = x_i \pm \Delta x, we have

G=1cΔt2Δx(eikΔxeikΔx).\begin{align} G = 1 - \frac{c \Delta t}{2\Delta x} \left(e^{ik\Delta x} - e^{-ik\Delta x}\right). \end{align}

Using Euler’s formula eiθeiθ=2isinθe^{i\theta} - e^{-i\theta} = 2i \sin\theta:

G=1icΔtΔxsin(kΔx)=1iσsin(kΔx)\begin{align} G = 1 - i \frac{c \Delta t}{\Delta x} \sin(k \Delta x) = 1 - i \sigma \sin(k \Delta x) \end{align}

where σcΔt/Δx\sigma \equiv c \Delta t/\Delta x is the Courant number.

Calculating the magnitude of GG, we obtain:

G2=1+σ2sin2(kΔx)>1\begin{align} |G|^2 = 1 + \sigma^2 \sin^2(k \Delta x) > 1 \end{align}

Since G>1|G| > 1 for any σ\sigma, the FTCS scheme is unconditionally unstable for the linear advection equation.

To overcome this limitation, we will introduce two more robust finite difference methods: the Upwind Scheme and the Lax-Wendroff Scheme. These methods enhance stability and accuracy, making them more suitable for solving advection-dominated problems.

Upwind Scheme

The Upwind Scheme is a finite difference method specifically designed to handle advection-dominated problems more effectively than symmetric schemes like FTCS. By incorporating the direction of wave propagation into the discretization of spatial derivatives, the upwind method enhances numerical stability and reduces non-physical oscillations.

In advection processes, information propagates in a specific direction determined by the flow velocity cc. The upwind scheme leverages this directional information to bias the spatial derivative approximation, ensuring that the numerical flux aligns with the physical transport direction. This directional bias significantly improves the stability of the numerical solution, especially when dealing with sharp gradients or discontinuities.

The upwind scheme discretizes the spatial derivative based on the sign of the advection speed cc:

  • For c>0c > 0 (flow to the right):

    uxuinui1nΔx\begin{align} \frac{\partial u}{\partial x} \approx \frac{u_i^n - u_{i-1}^n}{\Delta x} \end{align}
  • For c<0c < 0 (flow to the left):

    uxui+1nuinΔx\begin{align} \frac{\partial u}{\partial x} \approx \frac{u_{i+1}^n - u_i^n}{\Delta x} \end{align}

Assuming c>0c > 0 for this implementation, the upwind scheme update rule becomes:

uin+1=uincΔtΔx(uinui1n)\begin{align} u_i^{n+1} = u_i^n - \frac{c \Delta t}{\Delta x} \left( u_i^n - u_{i-1}^n \right) \end{align}

where:

  • uinu_i^n is the numerical approximation of uu at spatial index ii and time level nn,

  • Δt\Delta t and Δx\Delta x are the time and spatial step sizes, respectively.

The upwind scheme is actually simplier than the FTCS scheme. The following Python code implements it to solve the linear advection equation.

# Parameters

c  = 1.0    # advection speed
l  = 1.0    # domain size
dt = 0.005  # time step

nx = 100    # number of spatial points
nt = 200    # number of time steps
X, dx = np.linspace(0, l, nx, endpoint=False, retstep=True)  # spatial grid
U0    = np.sin(2*np.pi * X)  # initial condition
# Upwind scheme

def upwind(c, U0, dx, dt, n):
    sigma = c * dt / dx
    U = [U0]
    for _ in range(n):
        U0 = U[-1]
        U1 = U0 - sigma * (U0 - np.roll(U0,1))
        U.append(U1)
    return np.array(U)
U       = np.sin(2*np.pi * (X - c*dt*nt))  # analytical solution
Uupwind = upwind(c, U0, dx, dt, nt)        # numerical solution
plt.plot(X, U0,                label='Initial Condition')
plt.plot(X, U, ':',            label='Exact Solution')
plt.plot(X, Uupwind[-1], '.-', label='Upwind Scheme')
plt.xlabel('x')
plt.ylabel('u')
plt.legend()
anim = animate(X, Uupwind)

HTML(anim.to_html5_video())  # display animation
# anim.save('FTCS.mp4')        # save animation

Although the amplitude uu decrease as time evolve, the upwind scheme is at least stable!

# HANDSON: change `c`, `dt`, `dx`, or other parameters to observe how
#          the numerical solution changes.
# HANDSON: change the initial condition to, e.g., a boxcar function,
#          and observe how the numerical solution changes

Von Neumann Stability Analysis

Assuming again the numerical solution can be expressed as uin=Gneikxiu_i^n = G^n e^{ikx_i}, the upwind update equation becomes

Gn+1eikxi=Gneikxiσ(GneikxiGneikxi1)\begin{align} G^{n+1} e^{ikx_i} = G^n e^{ikx_i} - \sigma \left( G^n e^{ikx_i} - G^n e^{ikx_{i-1}} \right) \end{align}

where σcΔt/Δx\sigma \equiv c \Delta t/\Delta x is again the Courant number.

Divide both sides by GneikxiG^n e^{ikx_i},

G=1σ(1eikΔx).\begin{align} G = 1 - \sigma \left( 1 - e^{-ik\Delta x} \right). \end{align}

Using Euler’s formula and separate the real and imaginary parts

G=[1σ+σcos(kΔx)]iσsin(kΔx).\begin{align} G = [1 - \sigma + \sigma \cos(k\Delta x)] - i \sigma \sin(k\Delta x). \end{align}

Calculate G2|G|^2,

G2=[1σ+σcos(kΔx)]2+[σsin(kΔx)]2=(1σ)2+2(1σ)σcos(kΔx)+σ2cos2(kΔx)+σ2sin2(kΔx)\begin{align} |G|^2 &= [1 - \sigma + \sigma \cos(k\Delta x)]^2 + [\sigma \sin(k\Delta x)]^2 \\ &= (1 - \sigma)^2 + 2(1 - \sigma)\sigma\cos(k\Delta x) + \sigma^2\cos^2(k\Delta x) + \sigma^2 \sin^2(k\Delta x) \end{align}

Using cos2θ+sin2θ=1\cos^2\theta + \sin^2\theta = 1,

G2=12σ+2σ2+2(1σ)σcos(kΔx).\begin{align} |G|^2 = 1 - 2\sigma + 2\sigma^2 + 2(1 - \sigma)\sigma\cos(k\Delta x). \end{align}

We can easily plot it:

Kdx = np.linspace(-np.pi, np.pi, 65)

def absG(sigma):
    return np.sqrt(1 - 2 * sigma + 2 * sigma*sigma + 2*(1-sigma)*sigma*np.cos(Kdx))

for sigma in [0.5, 1, 1.5]:
    plt.plot(Kdx, absG(sigma), label=r"$\sigma={}$".format(sigma))

plt.xlabel(r"$k\Delta x$")
plt.ylabel(r"|G|")
plt.legend()

Clearly, the maximum of G|G| depends on σ\sigma.

For σ<=1\sigma <= 1, consider cos(kΔx)=1\cos(k\Delta x) = 1 so that

Gmax2=1.\begin{align} |G|^2_{\text{max}} = 1. \end{align}

For σ>1\sigma > 1, consider cos(kΔx)=1\cos(k\Delta x) = -1 so that

Gmax2=12σ2>1.\begin{align} |G|^2_{\text{max}} = |1 - 2\sigma|^2 > 1. \end{align}

Therefore, the upwind scheme is stable as provided that the Courant number satisfies:

σ=cΔtΔx1.\begin{align} \sigma = \frac{c \Delta t}{\Delta x} \leq 1. \end{align}
# HANDSON: given what we know about stability now, change `c`, `dt`,
#          `dx`, or other parameters to observe how the numerical
#          solution changes.

Modified Equation Method

We observed the amplitude of the wave decreases when using the upwind scheme. This decay in amplitude is resemble of viscosity: in physical systems, viscosity acts to dissipate energy and smooth out oscillations. Similarly, many stable numerical schemes effectively remove “energy” from the discrete system in order to maintain stability. This is not surprising that the upwind method damps out u(x,t)u(x,t).

But how exactly does this damping arise from the discretization? To answer this, we turn to another powerful tool called the Modified Equation Method.

Whereas von Neumann stability analysis focuses on whether solutions grow or decay in time, modified equation analysis asks a different question:

What continuous differential equation is the numerical method really solving, up to leading-order truncation error?

By expanding the discrete update scheme in a Taylor series, we can write down an equivalent modified PDE. This PDE makes the numerical errors explicit, showing whether the scheme introduces artificial diffusion (numerical viscosity) or artificial dispersion (phase errors).

Modified Equation of Upwind Advection

  1. Express the Upwind Scheme Using Taylor Series Expansions

    Start with the upwind update equation:

    uin+1=uinσ(uinui1n),\begin{align} u_i^{n+1} = u_i^n - \sigma \left( u_i^n - u_{i-1}^n \right), \end{align}

    in addition to the grid point that we want to update, uinu_i^n, there are two additional grid points. They are uin+1u_i^{n+1} and ui1nu_{i-1}^n.

    Expand uin+1u_i^{n+1} and ui1nu_{i-1}^n around the point (xi,tn)(x_i, t^n) using Taylor series:

    uin+1=u(xi,tn)+Δtutx=xi,t=tn+Δt222ut2x=xi,t=tn+O(Δt3)ui1n=u(xi,tn)Δxuxx=xi,t=tn+Δx222ux2x=xi,t=tn+O(Δx3)\begin{align} u_i^{n+1} &= u(x_i, t^n) + \Delta t \left.\frac{\partial u}{\partial t}\right|_{x=x_i,t=t_n} + \frac{\Delta t^2}{2} \left.\frac{\partial^2 u}{\partial t^2}\right|_{x=x_i,t=t_n} + \mathcal{O}(\Delta t^3) \\ u_{i-1}^n &= u(x_i, t^n) - \Delta x \left.\frac{\partial u}{\partial x}\right|_{x=x_i,t=t_n} + \frac{\Delta x^2}{2} \left.\frac{\partial^2 u}{\partial x^2}\right|_{x=x_i,t=t_n} + \mathcal{O}(\Delta x^3) \end{align}

    Using the shorthands u˙u/t\dot{u} \equiv \partial u/\partial t and uu/xu' \equiv \partial u/\partial x, the above series can be written as

    uin+1=uin+Δtu˙in+Δt22u¨in+O(Δt3)ui1n=uinΔxuin+Δx22uin+O(Δx3)\begin{align} u_i^{n+1} &= u_i^n + \Delta t\,\dot{u}_i^n + \frac{\Delta t^2}{2}\,\ddot{u}_i^n + \mathcal{O}(\Delta t^3) \\ u_{i-1}^n &= u_i^n - \Delta x\,{u' }_i^n + \frac{\Delta x^2}{2}\,{u'' }_i^n + \mathcal{O}(\Delta x^3) \end{align}
  1. Substitute the Taylor Expansions into the Upwind Scheme

    Substitute the expansions into the upwind update equation:

    uin+Δtu˙in+Δt22u¨inuinσ[uin(uinΔxuin+Δx22uin)]\begin{align} u_i^n + \Delta t\,\dot{u}_i^n + \frac{\Delta t^2}{2}\,\ddot{u}_i^n \approx u_i^n - \sigma \left[ u_i^n - \left( u_i^n - \Delta x\,{u'}_i^n + \frac{\Delta x^2}{2}\,{u''}_i^n \right) \right] \end{align}

    Because the derivatives are exact (instead of numerical), we can drop the functions’ evaluations at the dicrete points xix_i and tnt^n. Simplify the equation, we have:

    Δtut+Δt222ut2σ(ΔxuxΔx222ux2)\begin{align} \Delta t \frac{\partial u}{\partial t} + \frac{\Delta t^2}{2} \frac{\partial^2 u}{\partial t^2} \approx -\sigma \left( \Delta x \frac{\partial u}{\partial x} - \frac{\Delta x^2}{2} \frac{\partial^2 u}{\partial x^2} \right) \end{align}
  1. Rearrange and Substitute the Original PDE

    Taking the spatial and temporal derivatives of the original advection equation u/t=cu/x\partial u/\partial t = -c \partial u/\partial x, we have

    2ut2=c2uxt,2utx=c2ux2\begin{align} \frac{\partial^2 u}{\partial t^2} = -c \frac{\partial^2 u}{\partial x\partial t}, \quad \frac{\partial^2 u}{\partial t\partial x} = -c \frac{\partial^2 u}{\partial x^2} \end{align}

    Combine, we obtain the two-way wave equation:

    2ut2=c22ux2.\begin{align} \frac{\partial^2 u}{\partial t^2} = c^2 \frac{\partial^2 u}{\partial x^2}. \end{align}

    Substituting the wave equation into the modified equation, we obtain:

    Δtut+c2Δt222ux2σ(ΔxuxΔx222ux2).\begin{align} \Delta t \frac{\partial u}{\partial t} + \frac{c^2\Delta t^2}{2} \frac{\partial^2 u}{\partial x^2} \approx -\sigma \left( \Delta x \frac{\partial u}{\partial x} - \frac{\Delta x^2}{2} \frac{\partial^2 u}{\partial x^2} \right). \end{align}
  1. Combine Like Terms

    Put back the definition of σ\sigma and rearrange,

    ut+c2Δt22ux2c(uxΔx22ux2)ut+cuxc2(ΔxcΔt)2ux2\begin{align} \frac{\partial u}{\partial t} + \frac{c^2\Delta t}{2} \frac{\partial^2 u}{\partial x^2} &\approx -c \left( \frac{\partial u}{\partial x} - \frac{\Delta x}{2} \frac{\partial^2 u}{\partial x^2} \right) \\ \frac{\partial u}{\partial t} +c \frac{\partial u}{\partial x} &\approx \frac{c}{2} (\Delta x - c\Delta t) \frac{\partial^2 u}{\partial x^2} \end{align}

    Define

    νupwindc(ΔxcΔt)/2\begin{align} \nu_\text{upwind} \equiv c(\Delta x - c\Delta t) / 2 \end{align}

    be the numerical diffusion coefficient, the above equation reduces to

    ut+cuxνupwind2ux2.\begin{align} \frac{\partial u}{\partial t} +c \frac{\partial u}{\partial x} \approx \nu_\text{upwind} \frac{\partial^2 u}{\partial x^2}. \end{align}

From the modified equation analysis, we found that the Upwind scheme introduces an additional term of the form

νupwinduxx,\begin{align} \nu_{\text{upwind}} u_{xx}, \end{align}

where νupwind(ΔxcΔt)\nu_{\text{upwind}} \propto (\Delta x - c \Delta t) depends on both the grid spacing and the chosen time step.

This term looks exactly like a viscous diffusion term, even though the original advection equation contains no viscosity at all. Hence the interpretation: the upwind scheme introduces “numerical viscosity/diffusion” to suppress instabilities.

Why numerical viscosity/diffusion matters?

  • Stabilizing Effect: Artificial viscosity is not necessarily a flaw. It is precisely what makes the Upwind Scheme stable, by damping out non-physical oscillations that can arise from discretization errors.

  • Trade-off with Accuracy: The downside is that this numerical viscosity smears out sharp features, such as wavefronts, contact discontinuities, or shocks. While this can improve stability, it comes at the cost of accuracy, especially in problems where sharp interfaces are physically meaningful.

  • Quantification via Modified Equation Analysis: The modified equation allows us to measure how much numerical diffusion is introduced and compare across schemes.

Thus, modified equation analysis connects stability theory (von Neumann analysis) and physical interpretation, showing how schemes balance between damping (diffusion) and oscillations (dispersion).

The artificial viscosity term also highlights the importance of the CFL condition:

σ=aΔtΔx1.\begin{align} \sigma = \frac{a \Delta t}{\Delta x} \leq 1. \end{align}
  • When σ1\sigma \leq 1, the artificial viscosity remains positive, ensuring stability.

  • When σ>1\sigma > 1, the coefficient becomes negative, meaning the scheme adds anti-diffusion rather than diffusion, which destabilize the solution.

Therefore, the CFL condition directly controls the magnitude and sign of the artificial viscosity introduced by the scheme.

Modified Equation of FTCS Advection

To determine how the FTCS scheme modifies the original linear advection equation by introducing additional terms that represent numerical errors, specifically focusing on artificial diffusion or dispersion.

  1. Start with the FTCS Update Equation

    Recalling the FTCS scheme for the linear advection equation is given by:

    uin+1=uincΔt2Δx(ui+1nui1n)\begin{align} u_i^{n+1} = u_i^n - \frac{c \Delta t}{2 \Delta x} \left( u_{i+1}^n - u_{i-1}^n \right) \end{align}

    where:

    • uinu_i^n is the numerical approximation of uu at spatial index ii and time level nn,

    • cc is the constant advection speed,

    • Δt\Delta t and Δx\Delta x are the time and spatial step sizes, respectively,

    • σ=cΔt/Δx\sigma = c \Delta t/\Delta x is the Courant number.

  1. Expand the Temporal and Spatial Terms Using Taylor Series

    Expand uin+1u_i^{n+1} around (xi,tn)(x_i, t^n):

    Undefined control sequence: \dddot at position 126: …Delta t^3}{6} {\̲d̲d̲d̲o̲t̲{u}\,}_i^n + \m…
    
    \begin{align}
         u_i^{n+1} = u_i^n + \Delta t \dot{u}_i^n
         + \frac{\Delta t^2}{2} \ddot{u}_i^n + \frac{\Delta t^3}{6} {\dddot{u}\,}_i^n + \mathcal{O}(\Delta t^3)
       \end{align}

    Expand ui+1nu_{i+1}^n and ui1nu_{i-1}^n around (xi,tn)(x_i, t^n):

    ui±1n=uin±Δxuin+Δx22uin±Δx36uin+O(Δx4)\begin{align} u_{i\pm1}^n &= u_i^n \pm \Delta x {u'}_i^n + \frac{\Delta x^2}{2} {u''}_i^n \pm \frac{\Delta x^3}{6} {u'''}_i^n + \mathcal{O}(\Delta x^4) \end{align}
  1. Substitute the Taylor Expansions into the FTCS Scheme

    Substitute the expansions into the FTCS update equation:

    Undefined control sequence: \dddot at position 110: …Delta t^3}{6} {\̲d̲d̲d̲o̲t̲{u}\,}_i^n \\
     …
    
    \begin{align}
         u_i^n &+ \Delta t \dot{u}_i^n + \frac{\Delta t^2}{2} \ddot{u}_i^n + \frac{\Delta t^3}{6} {\dddot{u}\,}_i^n \\
         &\approx u_i^n - \frac{c \Delta t}{2 \Delta x} \left[
           \left( u_i^n + \Delta x {u'}_i^n + \frac{\Delta x^2}{2} {u''}_i^n + \frac{\Delta x^3}{6} {u'''}_i^n \right) -
           \left( u_i^n - \Delta x {u'}_i^n + \frac{\Delta x^2}{2} {u''}_i^n - \frac{\Delta x^3}{6} {u'''}_i^n \right)
       \right]
       \end{align}

    Simplify,

    Undefined control sequence: \dddot at position 89: …Delta t^2}{6} {\̲d̲d̲d̲o̲t̲{u}\,}_i^n
        …
    
    \begin{align}
         \dot{u}_i^n + \frac{\Delta t}{2}\ddot{u}_i^n + \frac{\Delta t^2}{6} {\dddot{u}\,}_i^n
         &\approx - c\left[ {u'}_i^n + \frac{\Delta x^2}{6} {u'''}_i^n \right]
       \end{align}
  1. Substitute and Rearrange

    Similar to the upwind screen, we recall that the advection equation implies the wave equation 2u/t2=c22u/x2\partial^2 u/\partial t^2 = c^2 \partial^2 u/\partial x^2.

    Taking an additional time derivative, we obtain:

    3ut3=c23ux2t=c33ux3.\begin{align} \frac{\partial^3 u}{\partial t^3} = c^2 \frac{\partial^3 u}{\partial x^2 \partial t} = - c^3\frac{\partial^3 u}{\partial x^3}. \end{align}

    Substitute this into the modified equation, we obtain

    u˙in+c2Δt2uinc3Δt26uinc[uin+Δx26uin].\begin{align} \dot{u}_i^n + c^2 \frac{\Delta t}{2} {u''}_i^n - c^3 \frac{\Delta t^2}{6} {u'''}_i^n &\approx - c\left[ {u'}_i^n + \frac{\Delta x^2}{6} {u'''}_i^n \right]. \end{align}

    Rearrange and drop the indices ii and nn, the final modified equation is:

    ut+cuxc2(cΔt)2ux2+c6(c2Δt2Δx2)3ux3\begin{align} \frac{\partial u}{\partial t} + c \frac{\partial u}{\partial x} &\approx - \frac{c}{2} (c \Delta t ) \frac{\partial^2 u}{\partial x^2} + \frac{c}{6} (c^2 \Delta t^2 - \Delta x^2) \frac{\partial^3 u}{\partial x^3} \end{align}

The modified equation of the FTCS advection scheme has a second-order “anti-diffusion” term and a third-order “dispersive” term. These terms affect the numerical solution in several ways:

  1. Numerical Instability: Unlike the Upwind Scheme, which introduces artificial diffusion to enhance stability, the FTCS scheme has an anti-diffusion term that is unstable.

  2. Introduction of Dispersive Errors: The (higher order) term 3u/x3\partial^3 u/\partial x^3 represents a dispersive error that causes different wave components to travel at slightly different speeds. This leads to phase errors where waveforms become distorted over time, deviating from the exact solution.

  3. Impact on Solution Accuracy: The introduced dispersive term does not counteract the amplification of numerical errors. Instead, it modifies the original equation in a way that can exacerbate inaccuracies, especially for higher-frequency components of the solution. Over time, these errors accumulate, leading to significant deviations from the true solution, as evidenced by the von Neumann stability analysis.

  4. Reinforcement of Von Neumann Stability Findings: The modified equation analysis complements the von Neumann stability analysis by providing a physical interpretation of why the FTCS scheme is unstable. The introduced dispersive errors contribute to the amplification of numerical oscillations, aligning with the conclusion that G>1|G| > 1 for any σ>0\sigma > 0.

  5. Practical Considerations: Practitioners must recognize that the FTCS scheme not only fails to maintain stability but also introduces errors that distort the solution without providing any compensatory benefits.

Consequently, the FTCS scheme is unsuitable for solving advection-dominated PDEs where both stability and accuracy in capturing wave propagation are essential.

Lax-Wendroff Scheme

First-order schemes like the upwind method are simple to implement but often introduce significant numerical diffusion, which can blur important features of the solution. To address these limitations, higher-order schemes have been developed to provide more accurate and reliable results.

The Lax-Wendroff Scheme is a second-order accurate finite difference method designed to solve hyperbolic PDEs, such as the linear advection equation. Unlike first-order methods, the Lax-Wendroff scheme incorporates both temporal and spatial derivatives up to the second order. This allows it to capture wave propagation more accurately while minimizing numerical diffusion and dispersion.

The main advantage of the Lax-Wendroff Scheme is its ability to maintain higher accuracy without compromising stability. By extending the Taylor series expansion to include second-order terms, the scheme reduces the smearing effect seen in first-order methods. Additionally, it better preserves the shape and speed of waves, making it suitable for problems where precise wave behavior is crucial.

We begin by expanding u(x,t+Δt)u(x, t + \Delta t) in time around tt using a Taylor series up to second order:

u(x,t+Δt)=u(x,t)+Δtut+(Δt)222ut2+O(Δt3)\begin{align} u(x, t + \Delta t) = u(x, t) + \Delta t \frac{\partial u}{\partial t} + \frac{(\Delta t)^2}{2} \frac{\partial^2 u}{\partial t^2} + \mathcal{O}(\Delta t^3) \end{align}

Substitute the advection equation and the wave equation into the Taylor series expansion:

u(x,t+Δt)=u(x,t)cΔtux+c2(Δt)222ux2+O((Δt)3)\begin{align} u(x, t + \Delta t) = u(x, t) - c \Delta t \frac{\partial u}{\partial x} + \frac{c^2 (\Delta t)^2}{2} \frac{\partial^2 u}{\partial x^2} + \mathcal{O}((\Delta t)^3) \end{align}

and approximate the spatial derivatives using centered finite differences:

uxui+1nui1n2Δx2ux2ui+1n2uin+ui1n(Δx)2,\begin{align} \frac{\partial u}{\partial x} &\approx \frac{u_{i+1}^n - u_{i-1}^n}{2 \Delta x} \\ \frac{\partial^2 u}{\partial x^2} &\approx \frac{u_{i+1}^n - 2u_i^n + u_{i-1}^n}{(\Delta x)^2}, \end{align}

we obtain:

uin+1=uincΔt(ui+1nui1n2Δx)+c2Δt22(ui+1n2uin+ui1nΔx2)+O(Δt3)\begin{align} u_i^{n+1} = u_i^n - c \Delta t \left(\frac{u_{i+1}^n - u_{i-1}^n}{2 \Delta x}\right) + \frac{c^2 \Delta t^2}{2} \left(\frac{u_{i+1}^n - 2u_i^n + u_{i-1}^n}{\Delta x^2}\right) + \mathcal{O}(\Delta t^3) \end{align}

Simplify the equation to isolate uin+1u_i^{n+1}, we obtain the Lax-Wendroff scheme for the linear advection equation

uin+1=uincΔt2Δx(ui+1nui1n)+c2Δt22Δx2(ui+1n2uin+ui1n)\begin{align} u_i^{n+1} = u_i^n - \frac{c \Delta t}{2 \Delta x} (u_{i+1}^n - u_{i-1}^n) + \frac{c^2 \Delta t^2}{2 \Delta x^2} (u_{i+1}^n - 2u_i^n + u_{i-1}^n) \end{align}
# Parameters

c  = 1.0    # advection speed
l  = 1.0    # domain size
dt = 0.005  # time step

nx = 101    # number of spatial points
nt = 200    # number of time steps
X, dx = np.linspace(0, l, nx, endpoint=False, retstep=True)  # spatial grid
U0    = np.sin(2*np.pi * X)  # initial condition
# Lax-Wendroff scheme

def LW(c, U0, dx, dt, n):
    sigma = c * dt / dx
    U = [U0]
    for _ in range(n):
        U0 = U[-1]
        U1 = U0 - sigma       * (np.roll(U0,-1)        - np.roll(U0,1)) / 2 \
                + sigma*sigma * (np.roll(U0,-1) - 2*U0 + np.roll(U0,1)) / 2
        U.append(U1)
    return np.array(U)
U   = np.sin(2*np.pi * (X - c*dt*nt)) # analytical solution
ULW = LW(c, U0, dx, dt, nt)           # numerical solution
plt.plot(X, U0,            label='Initial Condition')
plt.plot(X, U,       ':',  label='Exact Solution')
plt.plot(X, ULW[-1], '.-', label='Lax-Wendroff')
plt.xlabel('x')
plt.ylabel('u')
plt.legend()
anim = animate(X, ULW)

HTML(anim.to_html5_video())  # display animation
# anim.save('FTCS.mp4')        # save animation

Von Neumann Stability Analysis

Following previous derivation, it is straightforward to show

G=1+σ2[cos(kΔx)1]iσsin(kΔx)\begin{align} G = 1 + \sigma^2[\cos(k\Delta x) - 1] - i \sigma\sin(k\Delta x) \end{align}

Therefore,

G2=1+4σ2sin4(kΔx2)(σ21)\begin{align} |G|^2 = 1 + 4\sigma^2\sin^4\left(\frac{k\Delta x}{2}\right)(\sigma^2 - 1) \end{align}

Hence, G1|G| \leq 1 for all kΔxk\Delta x iff σ1|\sigma| \leq 1. This lead to the same CFL condition

cΔtΔx1.\begin{align} |c| \frac{\Delta t}{\Delta x} \leq 1. \end{align}
# HANDSON: Perform the von Neumann stability analysis to the
#          Lax-Wendroff Scheme.

Modified Equation

Also following previous derivation, we can also show the modified equation be

ut+cuxc6(c2Δt2Δx2)3ux3\begin{align} \frac{\partial u}{\partial t} + c \frac{\partial u}{\partial x} &\approx \frac{c}{6} (c^2 \Delta t^2 - \Delta x^2) \frac{\partial^3 u}{\partial x^3} \end{align}

Note that this is the same as the FTCS modified equation but without the antidiffusion term.

Note also that when σ=1\sigma = 1, the 3u/x3\partial^3 u/\partial x^3 term vanishes at leading order. When σ1\sigma \ne 1, the 3u/x3\partial^3 u/\partial x^3 term create phase (dispersion) error. For σ<1|\sigma| < 1, there is also weak dissipation from higher-order terms.

# HANDSON: Perform modified equation analysis to the Lax-Wendroff
#          Scheme.