Code covered by the BSD License  

Highlights from
Chebfun

image thumbnail
from Chebfun by Chebfun Team
Numerical computation with functions instead of numbers.

Heat equation via EXPM

Heat equation via EXPM

Nick Trefethen, October 2010

(Chebfun example pde/Erosion.m)

A well-known PDE problem is the heat equation initial boundary-value problem posed for x in [a,b] and t > 0,

u_t = u_xx,  u(x,0) = u0(x)

with suitable boundary conditions. We can regard this as a time-dependent linear process

u_t = Lu

where L is the operator d^2/dx^2 on [a,b] with the same boundary conditions. The solution is

u(t) = e^(tL) u(0).

In Chebfun we can implement this idea using the EXPM command to compute the operator exponential. Here is an example with Neumann boundary conditions on the interval [0,6]. We start with quite an irregular initial function.

d = [0,6];
u0 = chebfun(@(x) sign((-1).^floor(x.^1.5)),d,'splitting','on');
LW = 'linewidth'; lw = 2; FS = 'fontsize'; fs = 16;
clf, plot(u0,LW,lw), grid on
title(sprintf('t = %4.2f     length = %d',0,length(u0)),FS,fs)
ax = [0 6 -1.2 1.2]; axis(ax)

Here's the solution at t = 0.01. Notice that the narrower spikes have lost more amplitude than the wider ones. The warning message is important: Chebfun does not always give its full accuracy for computations of this kind.

L = chebop(d);          % operator on domain [0,6]
L.op = @(u) diff(u,2);  % 2nd-derivative operator
L.lbc = @(u) diff(u);   % Neumann BC at left
L.rbc = @(u) diff(u);   % Neumann BC at right
dt = 0.01;
expmL = expm(dt*L);     % exponential of the operator
u = expmL*u0;
plot(u,LW,lw), axis(ax), grid on
title(sprintf('t = %4.2f     length = %d',0.01,length(u)),FS,fs)


figure
Warning: Nonsmooth initial data may degrade accuracy in the result. 

Here is the solution at t = 0.02. Now that the function is smooth, there are no further warning messages. The rightmost maximum has extra amplitude, since it effectively corresponded to a wider initial spike thanks to the Neumann boundary condition.

u = expmL*u;
plot(u,LW,lw), axis(ax), grid on
title(sprintf('t = %4.2f     length = %d',0.02,length(u)),FS,fs)

figure

At t = 0.1, there is not much of the original structure left. The length of the chebfun has also been reduced.

u = expm(0.08*L)*u;
plot(u,LW,lw), axis(ax), grid on
title(sprintf('t = %4.2f     length = %d',0.1,length(u)),FS,fs)

Contact us