Application Center - Maplesoft

App Preview:

The vibrating string: d'Alembert's formula

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application


 

1d-Wave.mws

Partial Differential Equations

The vibrating string: d'Alembert's formula.

Anton Dzhamay

Department of Mathematics

The University of Michigan

Ann Arbor, MI 48109

wPage: http://www.math.lsa.umich.edu/~adzham

email: adzham@umich.edu

Copyright  2004  by Anton Dzhamay

All rights reserved

Packages

Some packages that we use in this worksheet:

>    restart: with(plottools): with(plots):

Warning, the names arrow and changecoords have been redefined

Introduction

The goal of this worksheet is to illustrate the use of the method of characteristics and d'Alembert's formula for the one-dimentional wave equation (i.e., the vibrating string). The equation is diff(u(x,t),`$`(t,2)) = c^2*diff(u(x,t),`$`(x,2))   . Since the equation is second order in t   , we need to specify the initial position u(x,0) = f(x)    and the initial velocity diff(u(x,0),t) = g(x)   . If we consider this equation on the whole real line, then we do not need to worry about boundary conditions and the solution is given by the d'Alembert's formula:

>    u:=(x,t)->(f(x-c*t)+f(x+c*t))/2+int(1/(2*c)*g(v),v=x-c*t..x+c*t);

u := proc (x, t) options operator, arrow; 1/2*f(x-c*t)+1/2*f(x+c*t)+int(1/2*1/c*g(v),v = x-c*t .. x+c*t) end proc

For semi-infinite and finite intervals with homogeneous Dirichlet or Neumann boundary conditions the strategy is to extend the initial data to the whole real line in such a way that the boundary conditions are satisfied. It turns out that one has to take the odd extension about the boundary point for the Dirichlet boundary condition and the even extension for the Neumann boundary condition. In the examples below we illustrate this technique.

>   

Initialization

First we initialize some of the variables. Below T    is the time interval we are interested in, nch    is the number of characteristic curves that we want to plot per unit interval, and ntsteps    is the number of steps in the t    variable.

>    c:=2: nch:=3: T:=3: ntsteps:=25:

The shift command below allows us to combine the graph of the characteristics (which is two-dimensional) with the graph of the solution (three-dimensional).

>    shift:=transform((x,y)->[x,y,-0.1]):

In order to satisfy different boundary conditions we need to take even and odd extensions of functions about x = 0    for half-line or about   x = 0    and x = L    for a finite interval.

We define the oddext0  ( evenext0 ) procedures that takes a function or an expression expr  in a variable var  and returns a functional operator in var  that is the odd (even) extension of expr  about the origin.

>    oddext0:=proc(expr,var)
   unapply(signum(var)*unapply(expr,var)(abs(var)),var);

end proc:

>    evenext0:=proc(expr,var)
   unapply(unapply(expr,var)(abs(var)),var);

end proc:

The procedures for even, odd, and periodc extensions of fucntions over the finite interval are defined similarly.

>    pext:=proc(expr,var,L)
   unapply(unapply(expr,var)(var - floor((var+L)/(2*L))*2*L),var)

end proc:

oddext:=proc(expr,var,L)

   local x;

   x:=var - floor((var+L)/(2*L))*2*L;

   unapply(signum(x)*unapply(expr,var)(abs(x)),var)

end proc:

evenext:=proc(expr,var,L)

   local x;

   x:=var - floor((var+L)/(2*L))*2*L;

   unapply(unapply(expr,var)(abs(x)),var)

end proc:

Example 1: "Pick"

In this example we take g(x) = 0    and take f(x)    to look like a "guitar pick" (note that this function has discontinuous derivatives, and so the corresponding solution is the weak  solution):

>    f:=x->piecewise(x < 1,0,x < 2,x-1,x < 3,3-x,0):g:=x->0:
plot([f(x),g(x)],x=-1..5,color=[red,green],thickness=2,

scaling=constrained,title="Initial Conditions",legend=["f(x)","g(x)"]);

[Maple Plot]

Now we can see how the initial profile changes in time:

>    display([seq(plot(u(x,t/ntsteps),x=-1..5,color=red,thickness=2),
t=0..T*ntsteps)],scaling=constrained,insequence=true,title="Pick");

[Maple Plot]

The plot below helps to see how the initial profile splits into the left and right moving waves.

>    display([seq(plot([u(x,t/ntsteps),1/2*f(x-c*t/ntsteps),1/2*f(x+c*t/ntsteps)],x=-1..5,
color=[red,green,blue],thickness=2),

t=0..T*ntsteps)],scaling=constrained,insequence=true);

[Maple Plot]

And this is how the graph of the solution looks like (from the top). We color it according to the height of the solution, and this makes it easy to see the left and right waves. The characteristics are plotted below, rotate the graph to see them.

>    char_r:=display([seq(plot([c*t+1/nch*x,t,t=0..T],color=red,thickness=1),x=-1*nch..5*nch)]):
char_l:=display([seq(plot([-c*t+1/nch*x,t,t=0..T],color=black,thickness=1),x=-1*nch..5*nch)]):

>    display([plot3d(u(x,t),x=-1..5,t=0..T,axes=boxed,scaling=constrained,numpoints=2000,
style=patchnogrid,shading=zhue),

shift(char_r),shift(char_l)],orientation=[-90,0],view=[-1..5,0..T,-0.1..1]);

[Maple Plot]

Example 2: "Hammer Blow"

In this example we take f(x) = 0    and take g(x)    to represent kicking the string by a hammer:

>    f:=x->0:g:=x->piecewise(x < 2,0,x < 3,1,0):
plot([f(x),g(x)],x=-1..5,color=[red,green],thickness=2,

scaling=constrained,title="Initial Conditions",legend=["f(x)","g(x)"]);

[Maple Plot]

Now we can see how the initial profile changes in time (this calculation may take a while):

>    display([seq(plot(u(x,t/ntsteps),x=-1..5,color=red,thickness=2),
t=0..T*ntsteps)],scaling=constrained,insequence=true,title="Hammer Blow");

[Maple Plot]

View from the top and the characteristics:

>    char_r:=display([seq(plot([c*t+1/nch*x,t,t=0..T],color=red,thickness=1),x=-1*nch..5*nch)]):
char_l:=display([seq(plot([-c*t+1/nch*x,t,t=0..T],color=black,thickness=1),x=-1*nch..5*nch)]):

>    display([plot3d(u(x,t),x=-1..5,t=0..T,axes=boxed,scaling=constrained,numpoints=2000,
style=patchnogrid,shading=zhue),

shift(char_r),shift(char_l)],orientation=[-90,0],view=[-1..5,0..T,-0.1..0.3]);

[Maple Plot]

Note that there are different (color) zones, in each of these zones the solution is given by a different analytic formula.The following "close-up" picture helps to see the zones more clearly

>    display([plot3d(u(x,t),x=1.5..3.5,t=0..1,axes=boxed,numpoints=2000,
style=patchcontour,shading=zhue),

shift(char_r),shift(char_l)],orientation=[-90,0],view=[1.5..3.5,0..1,-0.1..0.3]);

[Maple Plot]

Example 3: Left Wall (Dirichlet BC)

In order to satisfy the Dirichlet BC at x = 0    we need to extend our functions from the right half-line to the whole line by taking the odd  extension about 0.  

>    ff:=piecewise(x < 1,0,x < 2,x-1,x < 3,3-x,0):g:=x->0:
f:=oddext0(ff,x):

plot([ff(x),f(x)],x=-5..5,color=[red,green],thickness=2,

scaling=constrained,title="f(x) and its odd extension");

[Maple Plot]

>    f(x);

signum(x)*PIECEWISE([0, abs(x) < 1],[abs(x)-1, abs(x) < 2],[3-abs(x), abs(x) < 3],[0, otherwise])

Now we can see how the initial profile changes in time:

>    T:=4:

>    display([seq(plot(u(x,t/ntsteps),x=0..5,color=red,thickness=2),
t=0..T*ntsteps)],scaling=constrained,insequence=true,title="Left Wall (Dirichlet)");

[Maple Plot]

It looks like the left-moving wave hits the wall and gets flipped and reflected. Note that u(0,t) = 0    for all t   . Peeking "behind" the wall we see the "image" right-moving wave emerging from the wall simultaneously with the left-moving wave disappearing into the wall:

>    movie:=display([seq(plot([u(x,t/ntsteps),1/2*f(x-c*t/ntsteps),1/2*f(x+c*t/ntsteps)],x=-5..5,
color=[red,green,blue],thickness=2),

t=0..T*ntsteps)],scaling=constrained,insequence=true):

>    display([movie,rectangle([-5,5],[0,-5],color=grey)],view=[-3..5,-1..1],title="Left Wall (Dirichlet)");

[Maple Plot]

And this is how the graph of the solution looks like (from the top).

>    plot3d(u(x,t),x=0..5,t=0..T,axes=boxed,scaling=constrained,numpoints=2000,
style=patchnogrid,shading=zhue,orientation=[-90,0]);

[Maple Plot]

Example 4: Left Wall (Neumann BC)

In order to satisfy the Neumann BC at x = 0    we need to extend our functions from the right half-line to the whole line by taking the even extension about x = 0   .

>    ff:=x->piecewise(x < 1,0,x < 2,x-1,x < 3,3-x,0):g:=x->0:
f:=evenext0(ff(x),x):

plot([ff(x),f(x)],x=-5..5,color=[red,green],thickness=2,numpoints=2000,

scaling=constrained,title="f(x) and its even extension");

[Maple Plot]

>    T:=4:

>    display([seq(plot(u(x,t/ntsteps),x=0..5,color=red,thickness=2),
t=0..T*ntsteps)],scaling=constrained,insequence=true,title="Left Wall (Neumann)");

[Maple Plot]

Again, let's "peek" behind the wall:

>    movie:=display([seq(plot([u(x,t/ntsteps),1/2*f(x-c*t/ntsteps),1/2*f(x+c*t/ntsteps)],x=-5..5,
color=[red,green,blue],thickness=2),

t=0..T*ntsteps)],scaling=constrained,insequence=true):

>    display([movie,rectangle([-5,5],[0,-5],color=grey)],view=[-3..5,-1..1],title="Left Wall (Neumann BC)");

[Maple Plot]

>    plot3d(u(x,t),x=0..5,t=0..T,axes=boxed,scaling=constrained,numpoints=2000,
style=patchnogrid,shading=zhue,orientation=[-90,0]);

[Maple Plot]

Example 5: Two Walls (Mixed)

In order to satisfy the Neumann BC at x = L    we take an even  extension about x = L    and then to satisfy the Dirichlet BC at x = 0    we take an odd  extension about the origin. This gives us the correct extension on the interval [-2*L, 2*L]   , and then we extend it periodically to the whole real line. (In the example below L = 4   .) This is a very non-optimal way to define such an extension, but it is enough for our purposes.

>    ff:=x->piecewise(x < 1,0,x < 2,x-1,x < 3,3-x,0):g:=x->0:
f:=pext(oddext0(evenext(ff(x),x,4)(x),x)(x),x,8):

plot([ff(x),f(x)],x=-10..10,color=[red,green],thickness=2,

scaling=constrained,title="f(x) and its extension");

[Maple Plot]

Now we can see how the initial profile changes in time:

>    T:=8: ntsteps:=15:

>    display([seq(plot(u(x,t/ntsteps),x=0..4,color=red,thickness=2),
t=0..T*ntsteps)],scaling=constrained,insequence=true,title="Left Dirichlet and Right Neumann BC");

[Maple Plot]

"Peeking behind the walls" shows us the left and right moving waves:

>    movie:=display([seq(plot([u(x,t/ntsteps),1/2*f(x-c*t/ntsteps),1/2*f(x+c*t/ntsteps)],x=-5..9,
color=[red,green,blue],thickness=2),

t=0..T*ntsteps)],scaling=constrained,insequence=true):

>    display([movie,rectangle([-5,5],[0,-5],color=grey),
rectangle([4,5],[9,-5],color=grey)],view=[-5..9,-1..1]);

[Maple Plot]

Looking at the graph of the solution (from the top) we can see the characteristics "bounching off the walls":

>    plot3d(u(x,t),x=0..4,t=0..T,axes=boxed,scaling=constrained,numpoints=2000,
style=patchnogrid,shading=zhue,orientation=[-90,0]);

[Maple Plot]

Example 6: Two Walls (Dirichlet)

This time we need to take the odd  extension of f(x)    about both x = 0    and x = L   .  

>    ff:=x->x^2*(1-x):g:=x->0:
f:=oddext(ff(x),x,1):

plot([ff(x),f(x)],x=-3..3,color=[red,green],thickness=2,

scaling=constrained,title="f(x) and its odd extension",view=-1/2..1/2);

[Maple Plot]

>    T:=4:

>    display([seq(plot(u(x,t/ntsteps),x=0..1,color=red,thickness=2),
t=0..T*ntsteps)],scaling=unconstrained,insequence=true);

[Maple Plot]

And here are the left and right-waves (set animation to cycle for a better movie):

>    movie:=display([seq(plot([u(x,t/ntsteps),1/2*f(x-c*t/ntsteps),1/2*f(x+c*t/ntsteps)],x=-2..3,
color=[red,green,blue],thickness=2),

t=0..T*ntsteps)],scaling=constrained,insequence=true):

>    display([movie,rectangle([-5,0.2],[0,-0.2],color=grey),rectangle([1,0.2],[3,-0.2],color=grey)],
scaling=unconstrained);

[Maple Plot]

>    plot3d(u(x,t),x=0..1,t=0..3,axes=boxed,scaling=constrained,numpoints=2000,
style=patchnogrid,shading=zhue,orientation=[-90,0]);

[Maple Plot]

>   

References

  • Walter A. Strauss, Partial Differential Equations: An Introduction, Wiley, 1992
  • Richard Haberman, Elementary Applied Partial Differential Equations, 3rd edition, Prentice Hall

Disclaimer

"While every effort has been made to validate the solutions in this worksheet, Waterloo Maple Inc. and the contributors are not responsible for any errors contained and are not liable for any damages resulting from the use of this material."