We want to calculate the displacement field
for any time
by solving the wave equation
:
At initial time
the displacement
and the velocity
are given:
Here we are modelling a point source at the point
, in the numerical solution we
set the initial displacement to be
in a sphere of small radius around the point
.
We use an explicit time-integration scheme to calculate the displacement field
at
certain time marks
where
with time step size
. In the following the upper index
refers to values at time
. We use the Verlet scheme with constant time step size
which is defined by
In our case
is given by
In each time step we have to solve this problem to get the acceleration
and we will
use the LinearPDE class of the esys.escript.linearPDEs to do so. The general form of the PDE defined through
the LinearPDE class is discussed in Section 4.1. The form which is relevant here are
With
we can identify the values to be assigned to
,
:
The following script defines a the function wavePropagation which
implements the Verlet scheme to solve our wave propagation problem.
The argument domain which is a Domain class object
defines the domain of the problem. h and tend are the step size
and the time mark after which the simulation will be terminated respectively. lam, mu and
rho are material properties.
Notice that
all coefficients of the PDE which are independent from time
are set outside the while
loop. This allows the LinearPDE class to reuse information as much as possible
when iterating over time.
We have seen most of the functions in previous examples but there are some new functions here:
grad(u) returns the gradient
of
(in fact grad(g)[i,j]=
).
It is pointed out that in general there are restrictions on the argument of the grad function, for instance
for esys.finley the statement grad(grad(u)) will raise an exception.
trace(g) returns the sum of the main diagonal elements g[k,k] of g
and transpose(g) returns the transposed of the matrix g (ie.
).
We initialize the values of u and u_last to be
for a small
sphere of radius, src_radius around the point source located at
.
These satisfy the initial conditions defined in Equation (2.34).
The output U_pc.out and vtu files are saved in a directory called data.
The U_pc.out stores 4 columns of data:
respectively, where
are the
components of
the displacement vector
at the point source. These can be
plotted easily using any plotting package. In gnuplot the command:
plot 'U_pc.out' u 1:2 title 'U_x' w l lw 2, 'U_pc.out' u 1:3 title 'U_y' w l lw 2,
'U_pc.out' u 1:4 title 'U_z' w l lw 2 will reproduce Figure 2.6.
The statement myPDE.setLumpingOn() switches on the usage of an aggressive approximation of the PDE operator, in this case formed by the coefficient D (actually the discrete version of the PDE operator is approximated by a diagonal matrix). The approximation allows, at the costs of an additional error, very fast solving of the PDE when the solution is requested. In the general case, the presence of A, B or C setLumpingOn will produce wrong results.
One of the big advantages of the Verlet scheme is the fact that the problem to be solved
in each time step is very simple and does not involve any spatial derivatives (which actually allows us to use lumping).
The problem becomes so simple because we use the stress from the last time step rather then the stress which is
actually present at the current time step. Schemes using this approach are called an explicit time integration
scheme . The
backward Euler scheme we have used in Chapter 2.2 is
an example of an implicit schemes
. In this case one uses the actual status of
each variable at a particular time rather then values from previous time steps. This will lead to a problem which is
more expensive to solve, in particular for non-linear problems.
Although
explicit time integration schemes are cheap to finalize a single time step, they need significantly smaller time
steps then implicit schemes and can suffer from stability problems. Therefore they need a
very careful selection of the time step size
.
An easy, heuristic way of choosing an appropriate
time step size is the Courant condition
which says that within a time step a information should not travel further than a cell used in the
discretization scheme. In the case of the wave equation the velocity of a (p-) wave is given as
so one should choose
from
The following script uses the wavePropagation function to solve the
wave equation for a point source located at the bottom face of a block. The width of the block in
each direction on the bottom face is
km (
and
directions ie. l0 and l1).
ne gives the number of elements in
and
directions.
The depth of the block is aligned with the
-direction.
The depth (l2) of the block in
the
-direction is chosen so that there are 10 elements and the magnitude of the
of the depth is chosen such that the elements
become cubic. We chose 10 for the number of elements in
-direction so that the
computation would be faster. Brick(
) is an esys.finley function which creates a rectangular mesh
with
elements over the brick
.
The script is available as wave.py in the example directory . Before running the code make sure you have created a directory called data in the current
working directory.
To visualize the results from the data directory:
mayavi -d usoln.1.vtu -m SurfaceMap &You can rotate this figure by clicking on it with the mouse and moving it around. Again use Configure Data to move backwards and forward in time, and also to choose the results (acceleration, displacement or
esys@esscc.uq.edu.au