Skip to content

3.1 Tendency Term and Simple Time Evolution Models


Learning Objectives

After completing this lecture, students should be able to:

  • explain the concept of a tendency term in time-evolution equations
  • interpret the continuous and discrete forms of the governing equation
  • implement forward, backward, and central schemes for time integration
  • compare analytical and numerical solutions and evaluate numerical errors

Concept

Many climate processes evolve in time according to a tendency equation, which describes how a variable changes in response to a forcing.

The simplest form is:

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

where \(T\) represents temperature and \(F\) represents the forcing.

In general, this formulation applies to many variables in the climate system, such as moisture (\(q\)), zonal wind (\(u\)), and others. The left-hand side, \(\partial T / \partial t\), is the time derivative, which is called the tendency term.

In realistic applications, both \(T\) and \(F\) are functions of space and time (i.e., \(x, y, z,\) and \(t\)). However, in this lecture, we consider a simplified case in which the system depends only on time. This allows us to focus on the fundamental behavior of time evolution.

We prescribe a sinusoidal forcing, which mimics periodic processes such as the seasonal cycle.

We then solve this equation in two ways:

  • analytically, to obtain the exact solution
  • numerically, to approximate the solution using discrete time steps

By comparing these solutions, we evaluate how numerical schemes approximate the continuous system and introduce errors.


Model / Equation

The original equation is:

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

We prescribe the forcing as

\[ F = a \, \omega \sin(\omega t) \]

The governing equation becomes

\[ \frac{\partial T}{\partial t} = a \, \omega \sin(\omega t) \]

where:

  • \(T\) : temperature (state variable)
  • \(F\) : forcing
  • \(a\) : amplitude
  • \(\omega\) : angular frequency
  • \(t\) : time

Analytical Solution

Integrating the equation gives:

\[ T(t) = -a \cos(\omega t) + C \]

For simplicity, we set

\[ C = 0 \]

so that

\[ T(t) = -a \cos(\omega t) \]

This represents a periodic temperature evolution with amplitude \(a\).

Numerical Approximation

We discretize time as

\[ t_n = n \Delta t \]

and define

\[ T^n = T(t_n), \quad F^n = F(t_n) \]

Using this notation, the time derivative is approximated by finite differences.

Forward scheme:

\[ T^{n+1} = T^n + \Delta t \, F^n \]

Backward scheme:

\[ T^{n+1} = T^n + \Delta t \, F^{n+1} \]

Central scheme:

\[ T^{n+1} = T^{n-1} + 2 \Delta t \, F^n \]

The analytical solution is used as a reference to evaluate numerical accuracy.

Sample Code

An initail python script for this lecture are provided below.

Initial template:

This script includes:

  • parameter settings
  • time coordinate setting
  • prescribed forcing
  • analytical solution
  • an initial numerical array
  • a three-panel plot for forcing, temperature, and error

Example command:

$ conda activate env_psc6125
$ python 3_1-tendency_initial.py

Exercise

Follow the steps below to build the numerical solutions gradually.

Step 1. Modify the Parameters and Examine the Analytical Solution

Start from the initial template and modify the parameters as follows:

nmon = 6.0
nyear = 2.0
dt = 0.5

a = 1.0
c = 0.0

First, create a copy of the original script:

$ cp 3_1-tendency_initial.py 3_1-tendency_step1.py

Then run the script and examine:

  • the frequency and period of the oscillation
  • the prescribed forcing \(F(t)\)
  • the analytical solution \(T_{\mathrm{ana}}(t)\)

Focus on the following questions:

  • How does increasing nyear affect the total simulation length?
  • How does changing nmon affect the period of the oscillation?
  • How does changing dt affect the time resolution and representation of the oscillation?
  • How do a and c affect the amplitude and mean state of \(T(t)\)?
  • What happens to the error when the numerical solution is not yet properly implemented?

After exploring these parameter sensitivities, update the script to use the following final configuration for the remaining steps:

nmon = 12.0
nyear = 5.0
dt = 1.0

a = 5.0
c = 0.5

This configuration will be used as the reference case for comparing numerical schemes.


Step 2. Implement the Forward Scheme

In this step, we replace the placeholder numerical solution with a physically meaningful time integration.

Create a copy of the step1 script:

$ cp 3_1-tendency_step1.py 3_1-tendency_step2.py

Start from the modified code:

T_num1 = np.zeros(nt)

# Initial condition
T_num1[0] = 0.0

# Do-loop from n=0 to N-2
for n in range(nt - 1):
    T_num1[n + 1] = 1.0

This implementation assigns a constant value at each time step and does not represent the governing equation.

Step 2.1 Replace with the Forward Scheme

The forward difference scheme is given by

\[ T^{n+1} = T^n + \Delta t \, F^{n} \]

Modify the loop as follows:

for n in range(nt - 1):
    T_num1[n + 1] = T_num1[n] + dt * F[n]

Step 2.2 Update the Initial Condition

To make a consistent comparison with the analytical solution, update the initial condition:

T_num1[0] = T_ana[0]

Step 2.3 Update the Plot

Add T_num1 to the temperature panel with line-mark plot:

axes[1].plot(t, T_num1, 'o-', label='Forward')

Compute and plot the error:

err1 = T_num1 - T_ana
axes[2].plot(t, err1, 'o-', label='Forward error')

Step 2.4 Examine the Result

After implementing the forward scheme, examine the following:

  • Does the numerical solution follow the analytical solution?
  • How does the error evolve over time?
  • Does the solution show any phase shift or amplitude error?

This step introduces the basic idea of time integration using a discrete scheme.


Step 3. Add the Backward Scheme

In this step, extend the forward-scheme code by adding the backward scheme.
This scheme will be compared with the analytical solution and the forward scheme.

First, create a copy of the Step 2 script:

$ cp 3_1-tendency_step2.py 3_1-tendency_step3.py

Create a new numerical array and set the initial condition:

T_num2 = np.zeros(nt)
T_num2[0] = T_ana[0]

The backward scheme is written as

\[ T^{n+1} = T^n + \Delta t \, F^{n+1} \]

In Python, implement it as follows:

for n in range(nt - 1):
    T_num2[n + 1] = T_num2[n] + dt * F[n + 1]

Add T_num2 to the temperature plot:

axes[1].plot(t, T_num2, 's-', color='C2', label='Backward')

Then compute and plot the error:

err2 = T_num2 - T_ana
axes[2].plot(t, err2, 's-', color='C2', label='Backward error')

Run the script and compare the backward solution with the forward solution and the analytical solution.

Focus on the following questions:

  • How does the backward solution differ from the forward solution?
  • Does the backward scheme show a different phase error or amplitude error?
  • How does the error evolve over time?

Step 4. Implement the Central Scheme

In this step, we introduce the central scheme, which differs from the previous methods because it requires two time levels.

First, create a copy of the Step 3 script:

$ cp 3_1-tendency_step3.py 3_1-tendency_step4.py

The central scheme is written as

\[ T^{n+1} = T^{n-1} + 2 \Delta t \, F^n \]

Initial attempt

Create a new numerical array with a single initial condition:

T_num3 = np.zeros(nt)
T_num3[0] = T_ana[0]

Then attempt to implement the central scheme:

for n in range(nt - 1):
    T_num3[n + 1] = T_num3[n - 1] + 2.0 * dt * F[n]

Update the plot:

err3 = T_num3 - T_ana

axes[1].plot(t, T_num3, '^-', color='C0', label='Central')

axes[2].plot(t, err3, '^-', color='C0', label='Central error')

Run the script and examine the result carefully.

Although the code runs without an error message, the implementation is still incorrect. At n = 0, the term T_num3[n - 1] becomes T_num3[-1], which refers to the last element of the array in Python. This does not represent the intended numerical method.

This demonstrates an important lesson: a script may run successfully even when the numerical scheme is not implemented correctly.

Add a second initial condition

To properly apply the central scheme, we must specify both \(T^0\) and \(T^1\).

Test the following two approaches:

Option 1: Use the analytical solution

T_num3[1] = T_ana[1]

Option 2: Use a forward step

T_num3[1] = T_num3[0] + dt * F[0]

Then revise the loop so that the integration starts from n = 1:

for n in range(1, nt - 1):
    T_num3[n + 1] = T_num3[n - 1] + 2.0 * dt * F[n]

Run the script again and compare the updated result with the first attempt.

Compare the three schemes

Compare the central scheme with the forward and backward schemes:

  • T_num1 : forward
  • T_num2 : backward
  • T_num3 : central

Focus on the following questions:

  • Why does the central scheme require two initial conditions?
  • Why does the first attempt run without an error message even though it is incorrect?
  • Which initialization method produces a more accurate solution?
  • How does the error evolve over time compared with the forward and backward schemes?

This step introduces an important concept:
the central scheme is a two-step method, and its accuracy depends on how it is initialized.


Step 5. Modify the Forcing: Add a Constant Term

In this step, we extend the forcing by adding a constant term.
This allows us to simulate a system with both a periodic component and a long-term trend.

First, create a copy of the Step 4 script:

$ cp 3_1-tendency_step4.py 3_1-tendency_step5.py

Modify the parameters

Add a new parameter:

d = 0.1

Modify the forcing

Update the forcing term as follows:

F = a * w * np.sin(w * t) + d

This means the system now includes:

  • a periodic forcing (seasonal cycle)
  • a constant forcing (persistent tendency)

Update the analytical solution

The governing equation becomes

\[ \frac{dT}{dt} = a \, \omega \sin(\omega t) + d \]

Integrating this equation gives

\[ T(t) = -a \cos(\omega t) + d t + C \]

In the code, implement:

T_ana = -a * np.cos(w * t) + d * t + c

Run the model

Run the script and examine:

  • the forcing \(F(t)\)
  • the analytical solution \(T_{\mathrm{ana}}(t)\)
  • the numerical solutions (T_num1, T_num2, T_num3)

Interpret the results

Focus on the following questions:

  • How does adding a constant term \(d\) change the shape of \(F(t)\)?
  • How does the temperature evolution differ from the purely periodic case?
  • Why does \(T(t)\) now include a linear trend?
  • Do the numerical schemes still follow the analytical solution accurately?
  • Does the error grow differently compared to the previous case?

This experiment demonstrates that a constant forcing produces a linear trend in the state variable.
In climate systems, this is analogous to long-term forcing (e.g., radiative imbalance) superimposed on natural variability.


Key Points

  • the tendency equation describes the time evolution of a system driven by a forcing term
  • continuous equations must be discretized for numerical implementation
  • forward and backward schemes are one-step methods, while the central scheme is a two-step method
  • multi-step methods require additional initial conditions
  • numerical solutions approximate the analytical solution but introduce errors
  • the magnitude and behavior of errors depend on the numerical scheme and time step
  • adding a constant forcing term introduces a linear trend in the solution

Homework

Complete the following tasks using a modified version of the final script.

  1. Copy your final script and use a new set of parameters (choose your own values for nmon, nyear, dt, a, c, and d).

  2. Implement all three numerical schemes:

  • forward (T_num1)
  • backward (T_num2)
  • central (T_num3)
  1. Generate a three-panel figure showing:
  • prescribed forcing
  • analytical and numerical solutions
  • numerical errors
  1. Compare the performance of the three schemes:
  • Which scheme produces the smallest error?
  • How does the time step (dt) affect the accuracy?
  • How does the choice of initial condition affect the central scheme?
  1. Provide a short written interpretation (1–2 paragraphs) describing:
  • the differences among the numerical schemes
  • the impact of your chosen parameters on the results
  • the relationship between forcing and the resulting temperature evolution

Submit your generated figure.