Skip to content

4.1 One-Dimensional Advection Equation


Learning Objectives

After completing this lecture, students should be able to:

  • understand the physical meaning of advection
  • interpret the one-dimensional advection equation
  • understand how numerical models approximate spatial derivatives
  • implement the upwind advection scheme
  • evaluate numerical advection solutions

Concept

Physical Meaning of Advection

Advection describes the transport of a quantity by a flow field.

Examples include:

  • transport of temperature by the wind
  • transport of water vapor by atmospheric circulation
  • transport of salinity by ocean currents
  • transport of pollutants in the atmosphere

One of the earliest applications of numerical weather prediction was the advection of atmospheric vorticity. In the pioneering numerical forecasts of the 1950s, researchers such as Charney and colleagues predicted the future atmospheric state by numerically integrating the advection of absolute vorticity.

Although modern weather and climate models contain many additional physical processes, advection remains one of the most fundamental components of atmospheric and oceanic models.


Simplifying Assumptions

To focus on the numerical treatment of advection, we make several simplifying assumptions.

First, we consider only one spatial dimension,

\[ x. \]

Second, the advection velocity is assumed to be constant,

\[ u = \text{constant}. \]

Finally, no forcing or damping terms are included.

Under these assumptions, the transported quantity changes only because it is carried by the background flow.


Advection Equation

The one-dimensional advection equation is

\[ \frac{\partial T}{\partial t} = -u \frac{\partial T}{\partial x}, \]

where

  • \(T\) is the transported quantity,
  • \(u\) is the constant advection velocity,
  • \(x\) is the spatial coordinate,
  • \(t\) is time.

The left-hand side represents the local tendency of the quantity, while the right-hand side represents the advection forcing.

If \(u>0\), the pattern propagates toward increasing \(x\). If \(u<0\), the pattern propagates toward decreasing \(x\).


Numerical Approximation

Numerical models cannot directly evaluate derivatives such as

\[ \frac{\partial T}{\partial t} \]

and

\[ \frac{\partial T}{\partial x}. \]

Instead, both temporal and spatial derivatives must be approximated using discrete values defined on a numerical grid.

This process converts the continuous differential equation into a discrete system that can be solved on a computer.

Several numerical schemes are commonly used for approximating derivatives.

For the spatial derivative:

  • Upwind scheme
  • Central-difference scheme
  • Spectral scheme

For the time derivative:

  • Forward Euler method
  • Runge-Kutta methods

In this section, we focus on the simplest combination:

  • Upwind scheme for the spatial derivative
  • Forward Euler method for the time derivative

This combination provides a straightforward introduction to numerical advection and allows us to understand the basic concepts of numerical stability and accuracy.

More advanced spatial and temporal discretization methods will be introduced in later sections.


Model / Equation

Governing Equation

The one-dimensional advection equation is

\[ \frac{\partial T}{\partial t} = -u \frac{\partial T}{\partial x}, \]

where

  • \(T\) is the transported quantity,
  • \(u\) is the constant advection velocity,
  • \(x\) is the spatial coordinate,
  • \(t\) is time.

The left-hand side represents the local tendency of \(T\), while the right-hand side represents advection by the background flow.


Analytical Solution

For a constant velocity \(u\), the analytical solution is

\[ T(x,t) = T(x-ut,0). \]

This solution indicates that the initial pattern simply translates with speed \(u\).

Consequently:

  • \(u>0\): propagation toward positive \(x\)
  • \(u<0\): propagation toward negative \(x\)

The shape and amplitude remain unchanged.


Discrete System

Numerical models replace the continuous derivatives with finite differences.

The tendency equation is

\[ \frac{\partial T}{\partial t} = F_{\rm adv}. \]

Using a finite-difference approximation, this can be written as

\[ \frac{\Delta T}{\Delta t} \approx F_{\rm adv}. \]

The Forward Euler approximation for the time derivative is

\[ \frac{\partial T}{\partial t} \approx \frac{T_i^{n+1}-T_i^n} {\Delta t}, \]

where \(i\) denotes the grid point and \(n\) denotes the time level.

The Forward Euler time-stepping equation is therefore

\[ T_i^{n+1} = T_i^n + \Delta t \left(F_{\rm adv}\right)_i^n. \]

For positive velocity (\(u>0\)), the upwind approximation for the spatial derivative is

\[ \frac{\partial T}{\partial x} \approx \frac{T_i^n-T_{i-1}^n} {\Delta x}. \]

Thus, the advection tendency becomes

\[ \left(F_{\rm adv}\right)_i^n = -u \frac{T_i^n-T_{i-1}^n} {\Delta x}. \]

The numerical model first computes the advection tendency \(F_{\rm adv}\), then updates \(T\) forward in time.


Connection to the Python Model

In the Python template, the advection tendency is computed inside the function

def advection_tendency(T, x, U):

This function returns \(F_{\rm adv}\).

The time integration loop then updates the field using

dTdt = advection_tendency(T, x, U)
T = T + DT * dTdt

This corresponds to

\[ T_i^{n+1} = T_i^n + \Delta t \left(F_{\rm adv}\right)_i^n. \]

In the exercises, students will modify the advection_tendency() function to implement the upwind scheme.


Sample Code

The template file for this section is

Run the script:

python 4_1-advection_template.py

The script produces

4_1-advection_template.mp4
4_1-advection_template.png

The template currently contains a bell-shaped initial condition and a placeholder advection tendency function. Numerical advection will be implemented in the exercises.

Optional: Linux server version

Some Linux servers do not support interactive graphics or include an MP4 video player. In this case, use the non-interactive Matplotlib backend (Agg) and automatically convert the MP4 animation to a GIF for quick preview.

import os
import matplotlib
matplotlib.use("Agg")

outfile_gif = script_name + ".gif"
os.system(
    f'ffmpeg -i {outfile_mp4} -vf "fps=10,scale=900:-1" {outfile_gif}'
)

The resulting GIF can be viewed using ImageMagick:

animate 4_1-advection_template.gif

A Linux-compatible version of the template is provided:


Exercise

Step 1. Implement the Upwind Scheme

In this step, we gradually build the numerical advection model.

First, run the template script without making any modifications:

$ python 4_1-advection_template.py

Examine the output files:

4_1-advection_template.mp4
4_1-advection_template.png

Questions:

  • Does the bell-shaped anomaly move?
  • Why does the solution remain unchanged?
  • Which part of the code controls the advection tendency?

The template currently uses

def advection_tendency(T, x, U):

    dTdt = np.zeros_like(T)

    return dTdt

Since the tendency is zero everywhere,

\[ F_{\rm adv}=0, \]

the field remains unchanged throughout the simulation.


Step 1.1 Modify the Model Parameters

Create a copy of the template script:

$ cp 4_1-advection_template.py 4_1-advection_step1.py

Modify the parameters as follows:

NT = 60
DT = 1.0

XMIN = -50.0
XMAX = 50.0
DX = 2.0

U = 0.5

X0 = -25.0
K = 15

These changes move the initial bell-shaped anomaly toward the left side of the domain and shorten the integration period.

Run the modified script:

$ python 4_1-advection_step1.py

Questions:

  • Has the anomaly moved?
  • Why is the solution still unchanged?
  • Why might it be useful to place the anomaly near the left side of the domain before implementing advection?

Step 1.2 Examine the Time Integration

Before implementing advection, examine how the model advances the solution in time.

Find the following section of the code:

for n in range(NT - 1):

    dTdt = advection_tendency(T, x, U)

    T = T + DT * dTdt

    T_save[n + 1, :] = T

This corresponds to the Forward Euler time-stepping equation

\[ T_i^{n+1} = T_i^n + \Delta t \left(F_{\rm adv}\right)_i^n. \]

The numerical model first computes the tendency \(F_{\rm adv}\), then updates the field forward by one time step.

Questions:

  • Which line computes the tendency?
  • Which line updates the temperature field?
  • What would happen if \(DT\) were increased?
  • Why does the model require both a tendency equation and a time integration scheme?

Step 1.3 Implement the Upwind Scheme

Find the function

def advection_tendency(T, x, U):

and replace it with

def advection_tendency(T, x, U):

    dTdt = np.zeros_like(T)

    for i in range(1, len(x)):
        dTdt[i] = -U * (T[i] - T[i-1]) / DX

    return dTdt

This implementation corresponds to

\[ \left(F_{\rm adv}\right)_i^n = -u \frac{T_i^n-T_{i-1}^n} {\Delta x}. \]

Run the script again:

$ python 4_1-advection_step1.py

Examine the output files:

4_1-advection_step1.mp4
4_1-advection_step1.png

Questions:

  • Does the bell-shaped anomaly move toward positive \(x\)?
  • Does the shape remain unchanged during the simulation?
  • Does the amplitude decrease with time?
  • Why does the upwind scheme use \(T_i-T_{i-1}\) when \(U>0\)?
  • What happens near the left boundary?

This step introduces the basic upwind scheme using an explicit loop. In the next step, we will replace the loop with a more efficient NumPy-based implementation.


Step 1.4 Implement the Upwind Scheme Using np.diff

The loop version is useful for understanding the numerical scheme, but NumPy can compute the same spatial difference more efficiently using np.diff.

Replace the advection_tendency() function with:

def advection_tendency(T, x, U):

    dTdt = np.zeros_like(T)

    dTdt[1:] = -U * np.diff(T) / DX

    return dTdt

Here,

np.diff(T)

computes

\[ T_i - T_{i-1} \]

for all grid points at once.

Run the script again:

$ python 4_1-advection_step1.py

Questions:

  • Does the result look the same as the loop version?
  • Why is np.diff more efficient than a Python loop?
  • Which version is easier to understand?
  • Which version is better for larger numerical models?

This step introduces the upwind scheme and shows two different implementations: an explicit loop and a vectorized NumPy calculation.


Step 2. Parameter Sensitivity

In this step, we examine how the numerical solution changes when the model parameters are modified. Focus on how grid spacing, time step, and advection velocity affect the solution.

Start from the Step 1 script:

$ cp 4_1-advection_step1.py 4_1-advection_step2.py

Use the np.diff version of the upwind scheme:

def advection_tendency(T, x, U):

    dTdt = np.zeros_like(T)

    dTdt[1:] = -U * np.diff(T) / DX

    return dTdt

Step 2.1 Increase the Spatial Resolution

First, reduce the grid spacing:

DX = 1.0

Keep the other parameters the same:

NT = 60
DT = 1.0
U = 0.5

Run the model:

$ python 4_1-advection_step2.py

Questions:

  • How does reducing DX affect the shape of the anomaly?
  • Does the solution look smoother than the DX = 2.0 case?
  • Does the anomaly move a different distance?

Step 2.2 Reduce the Time Step

Next, reduce the time step:

DT = 0.5
NT = 60

Keep

DX = 1.0
U = 0.5

Run the model again.

Questions:

  • How does reducing DT affect the animation?
  • Does the solution become smoother in time?
  • How does the total integration time compare with the previous experiment?
  • How far does the anomaly travel?

Because the total integration time is now

\[ NT \times DT = 30, \]

the simulation covers only half the time period of the previous experiment.


Step 2.3 Extend the Integration Length

Now keep the smaller time step but increase the number of time steps:

DT = 0.5
NT = 120

Run the model again.

Questions:

  • How does the solution compare with the previous experiment?
  • Does the anomaly travel farther?
  • Is the numerical solution smoother than the original case with DT = 1.0?
  • Why does increasing NT change the total integration length while leaving the numerical method unchanged?

The total integration time is now

\[ NT \times DT = 60, \]

which matches the original experiment.


Step 2.4 Reduce the Advection Velocity

Next, reduce the advection velocity:

U = 0.2

Keep

DX = 1.0
DT = 0.5
NT = 120

Run the model again.

Questions:

  • How does reducing U affect the propagation speed?
  • Does the anomaly move a shorter distance?
  • Does the shape of the anomaly change?

Step 2.5 Test a Higher-Resolution Case

Finally, test a higher-resolution configuration:

DX = 0.5
DT = 1.0
NT = 120
U = 0.7

Run the model.

This experiment may become numerically unstable because the time step is too large relative to the grid spacing and advection velocity.

Questions:

  • Does the model run successfully?
  • Does the solution remain smooth?
  • Do unrealistic oscillations or large values appear?

This experiment motivates the Courant-Friedrichs-Lewy (CFL) condition, which will be introduced in the next step.


Step 3. CFL Condition

In Step 2.5, the model became unstable when using

DX = 0.5
DT = 1.0
NT = 120
U = 0.7

This instability occurs because the time step is too large relative to the grid spacing and advection velocity.

The stability of the upwind advection scheme is controlled by the Courant-Friedrichs-Lewy number, or CFL number:

\[ C = \frac{U\Delta t}{\Delta x}. \]

The CFL number describes how far information travels during one time step relative to the grid spacing.

For the upwind scheme, the stability condition is

\[ C \le 1. \]

If

\[ C > 1, \]

the numerical solution becomes unstable because the flow travels more than one grid cell during a single time step.


Step 3.1 Calculate the CFL Number

For the unstable case in Step 2.5,

DX = 0.5
DT = 1.0
U = 0.7

the CFL number is

\[ C = \frac{0.7 \times 1.0}{0.5} = 1.4. \]

Since

\[ C > 1, \]

the numerical solution becomes unstable.

This result shows that increasing spatial resolution does not automatically improve the simulation. When \(\Delta x\) becomes smaller, the time step \(\Delta t\) must also become smaller to satisfy the CFL condition.

Similarly, stronger wind speed \(U\) requires a smaller time step because information travels farther during each time step.


Step 3.2 Restore Stability by Reducing the Time Step

To restore numerical stability, reduce the time step:

DX = 0.5
DT = 0.5
NT = 120
U = 0.7

The CFL number becomes

\[ C = \frac{0.7 \times 0.5}{0.5} = 0.7. \]

Run the model again.

Questions:

  • Does the solution become stable?
  • Does the bell-shaped anomaly propagate smoothly?
  • How does the solution compare with the unstable case?
  • Why does reducing DT restore stability?

Step 3.3 Test the Stability Limit

Next, test a case close to the CFL limit:

DX = 0.5
DT = 0.7
NT = 120
U = 0.7

The CFL number is

\[ C = \frac{0.7 \times 0.7}{0.5} = 0.98. \]

Run the model.

Questions:

  • Does the solution remain stable?
  • Does the anomaly retain its shape better than the \(C=0.7\) case?
  • What happens when the CFL number approaches 1?

Step 3.4 Test an Unstable Case Again

Now test a larger time step:

DX = 0.5
DT = 0.8
NT = 120
U = 0.7

The CFL number is

\[ C = \frac{0.7 \times 0.8}{0.5} = 1.12. \]

Run the model.

Questions:

  • Does the solution become unstable?
  • When does the instability first appear?
  • How does the instability differ from simple numerical diffusion?
  • Why does the model fail when \(C>1\)?

Step 3.5 Summary

Compare the following experiments:

Case DX DT U CFL Expected Behavior
Step 2.5 0.5 1.0 0.7 1.40 Unstable
Step 3.2 0.5 0.5 0.7 0.70 Stable
Step 3.3 0.5 0.7 0.7 0.98 Near stability limit
Step 3.4 0.5 0.8 0.7 1.12 Unstable

Focus on the following questions:

  • Which simulations are stable?
  • Which simulations are unstable?
  • How does reducing DT improve numerical stability?
  • Why does increasing spatial resolution require a smaller time step?
  • Why do stronger winds require a smaller time step?

The CFL condition is one of the most important stability criteria in numerical weather and climate modeling. It links the spatial resolution, time step, and flow speed into a single nondimensional number.


Key Points

  • Advection describes the transport of a quantity by a flow field.
  • The one-dimensional advection equation is one of the simplest transport equations used in numerical weather and climate models.
  • Numerical models approximate both temporal and spatial derivatives using discrete equations.
  • The upwind scheme uses information from the upstream direction of the flow to approximate the spatial derivative.
  • The Forward Euler method advances the solution forward in time using the computed tendency.
  • Numerical solutions depend on the spatial resolution (\(\Delta x\)), time step (\(\Delta t\)), and advection velocity (\(U\)).
  • The CFL number,
\[ C = \frac{U\Delta t}{\Delta x}, \]

provides a measure of numerical stability.

  • Stable solutions generally require
\[ C \le 1. \]
  • Increasing spatial resolution or increasing flow speed often requires a smaller time step to maintain stability.

Homework

Complete the following tasks:

  1. Generate one stable advection simulation with
DX = 0.5
DT = 0.5
U = 0.7
  1. Generate one unstable advection simulation with
DX = 0.5
DT = 1.0
U = 0.7
  1. Submit the corresponding MP4 animation files.

  2. Provide a short description (approximately 1 paragraph for each simulation) that addresses:

  • the behavior of the stable solution,
  • the behavior of the unstable solution,
  • the corresponding CFL number,
  • the relationship between the CFL condition and numerical stability.

Optional Further Experiments

Students interested in further exploration may investigate one or more of the following:

  • Test different advection velocities.
  • Test different spatial resolutions.
  • Test different time steps.
  • Move the initial bell-shaped anomaly to different locations.
  • Introduce multiple bell-shaped anomalies.
  • Investigate negative advection velocities (\(U < 0\)).
  • Determine experimentally the CFL number at which instability first develops.

Discussion Questions

  • Why does the upwind scheme use information from the upstream direction?
  • Why does the stable solution still exhibit numerical diffusion?
  • Why does increasing spatial resolution alone not guarantee a better solution?
  • Why do stronger winds require a smaller time step?
  • How might the CFL condition affect the computational cost of weather and climate models?