Wave Equation

Propagating waves

The "general" solution to the wave equation
    a^2 D[u,x,x] == D[u,t,t]
without consideration of boundary or initial conditions is given by:
    u[x_,t_] = v[x+a*t] + w[x-a*t]
where v[x] and w[x] are any (!) functions of x. Plotting u[x,t] as a function at various times t shows that the graph of v moves to the right while the graph of w moves to the left, both with a "velocity" of a. Eventually these two "waves" move through each other and emerge with their original shape on the other side. Let's look at an explicit example and set a==1.

v[x_] = If[x>=-1 && x<=1, 1-x^2, 0];

Plot[v[x],{x,-1.5,1.5},PlotStyle->RGBColor[1,0,0],
AspectRatio->Automatic]

w[x_] = If[x>=-1 && x<=1, 1, 0];

Plot[w[x],{x,-1.5,1.5},PlotStyle->RGBColor[1,0,0],
AspectRatio->Automatic]

u[x_,t_] = v[x+t] + w[x-t];

Do[
   Plot[u[x,t],{x,-4,4},
   PlotRange->{{-3.1,3.1},{0,2.1}},
   AspectRatio->Automatic],
{t,-2,2,0.2}]

Vibrating String

The differential equation for a vibrating string of length L is the wave equation
     a^2 D[u,x,x] == D[u,t,t]
subject to the boundary conditions
    u[0,t] == 0
    u[L,t] == 0
and the initial conditions
    u[x,0] == f[x]
    D[u[x,t],t]/.t->0 == g[x]
For consistency, the functions f and g must also satisfy:
    f[0] == f[L] == 0
    g[0] == g[L] == 0

Let us take L==1, a==1, and g[x]==0 (i.e., no initial velocity), and let f[x] be the triangular curve:

Clear[f];
f[x_ /; x>=0.0 && x<=0.5] := x;
f[x_ /; x> 0.5 && x<=1.0] := 1-x;

Plot[f[x], {x,0,1}]

We extend f to a periodic function for all real x by

Clear[h];
h[x_ /; x>=0.0 && x<=1.0] := f[x];
h[x_ /; x>1.0 ] := h[x-2];
h[x_ /; x<0.0] := -h[-x];

Plot[h[x],{x,-2,2},PlotRange->{-0.7,0.7},
AspectRatio->Automatic]

We know the solution of the wave equation is given by
    u[x,t] = v[x+t] + w[x-t]
If we choose
    v[x_] = (1/2)h[x]
    w[x_] = (1/2)h[x]
then the boundary conditions are satisfied:
    u[0,t] == (1/2)(h[t] + h[-t])
           == (1/2)(h[t] - h[t])
           == 0
    u[1,t] == (1/2)(h[1+t] + h[1-t])
           == (1/2)(h[t-1] - h[t-1])
           == 0
and the initial  conditions are satisfied:
    u[x,0] == (1/2)(h[x]+h[x])
           == f[x]
    D[u[x,t],t] == (1/2)(h[x+t] - h[x-t]) /. t->0
                == (1/2)(h[x+0] - h[x-0])
                == 0

Thus, the solution to the original problem is

u[x_,t_] = (1/2)(h[x+t] + h[x-t]);

Do[
   Plot[u[x,t],{x,0,1},
   PlotRange->{{0,1},{-0.5,0.5}}],
{t,0,1,0.05}]

The Fourier series expansion for the solution is
u[x_,t_] = Sum[b[n]Sin[n Pi x]Cos[n Pi t],{n,1,Infinity}]
where the coefficients are given by
b[n_] = 2 Integrate[f[x]Sin[n Pi x],{x,0,1/2}]

Let us work with some partial sums:

u[x_,t_,k_] = Sum[b[n]Sin[n Pi x]Cos[n Pi t],{n,1,k}];

b[n_] = 2 Integrate[f[x]Sin[n Pi x],{x,0,1}] /.
          {Cos[n Pi/2]->0,Sin[n Pi]->0}

u[x,t,5]

Do[
   Plot[u[x,t,5],{x,0,1},
   PlotRange->{{0,1},{-0.5,0.5}}],
{t,0,1,0.05}]

Let's look at the individual terms of the series that comprise the "natural modes" of the vibration (there are no even terms):

m[x_,t_,n_] = b[n]Sin[n Pi x]Cos[n Pi t]

Do[
   Plot[{m[x,t,1],m[x,t,3],m[x,t,5]},{x,0,1},
   PlotRange->{{0,1},{-0.33,0.33}},
   PlotStyle->{RGBColor[0,0,1],RGBColor[0,1,0],
               RGBColor[1,0,0]}],
{t,0,1,0.1}]

Here's another example using a cubic function for f. Note that we must make sure that f[0] == f[1] == 0.

Clear[f];
f[x_] := 10x(x-3/4)(x-1);

Plot[f[x], {x,0,1}]

The exact solution:

Clear[h];
h[x_ /; x>=0.0 && x<=1.0] := f[x];
h[x_ /; x>1.0 ] := h[x-2];
h[x_ /; x<0.0] := -h[-x];

Plot[h[x],{x,-2,2}]

u[x_,t_] = (1/2)(h[x+t] + h[x-t]);

Do[
   Plot[u[x,t],{x,0,1},
   PlotRange->{{0,1},{-1,1}}],
{t,0,1,0.05}]

The Fourier series approximation:

Clear[b];
u[x_,t_,k_] = Sum[b[n]Sin[n Pi x]Cos[n Pi t],{n,1,k}];

b[n_] = 2 Integrate[f[x]Sin[n Pi x],{x,0,1}] /.
          {Cos[n Pi/2]->0,Sin[n Pi]->0}

Do[
   Plot[u[x,t,3],{x,0,1},
   PlotRange->{{0,1},{-1,1}}],
{t,0,1,0.05}]

m[x_,t_,n_] = b[n]Sin[n Pi x]Cos[n Pi t]

Do[
   Plot[{m[x,t,1],m[x,t,2],m[x,t,3]},{x,0,1},
   PlotRange->{{0,1},{-0.75,0.75}},
   PlotStyle->{RGBColor[0,0,1],RGBColor[0,1,0],
               RGBColor[1,0,0]}],
{t,0,1,0.1}]