A 2D wave equation solver for a variable velocity model using the finite difference method.
Velocity model (top-left) and modelled pressure at increasing times. Reflections from the first velocity contrast can be seen from 4 seconds, and an emergent head-wave can be observed at 10-12 seconds.
The 2D wave equation is defined as follows:
where
A numerical solution to the wave equation can be obtained using the finite difference method (FDM). In order to implement the FDM, the space and time domains are discretized as follows:
The wave equation can then be expressed as
The components on the right-hand side were approximated by finite differences in two stages:
- The outer expression for each component was discretized as follows:
- The inner expressions were then approximated by the following:
The term on the left-hand side was then approximated by the following finite difference expression:
Substituting the above expressions into wave equation and rearranging yields the following formula for calculating the pressure,
where
This time-stepping expression is used to update the state of the inner points of the domain for each time increment.
Initial conditions are required at
where
illustrating that
The basic algorithm for the program can then be expressed as follows:
- Set initial condition for all points:
$u_{ij}^{l=0}=I(x,y)$ - Set fictitious prior displacement for inner points:
$u_{ij}^{l-1}=u_{ij}^{l}+\frac{\Psi_{ij}}{2}$ - While
$t\lt n_{t}$ , update inner points:$u_{ij}^{l+1}=2u_{ij}^{l}-u_{ij}^{l-1}+\Psi_{ij}$ - While
$t\lt n_{t}$ , initialise all points for the next time-step:$u_{ij}^{l-1}=u_{ij}^{l}$ ,$u_{ij}^{l}=u_{ij}^{l+1}$ ,$t=t+\Delta t$
Compile main.cpp
and run the program:
g++ main.cpp -o wave-sim
./wave-sim
Parameters will be automatically prompted from the user, or they can be defined in runfile.txt
where they are organised in the following order:
- Size of the model in
$x$ (lx
) - Size of the model in
$y$ (ly
) - Spatial grid spacing in
$x$ (dx
) - Total time to run simulation (
t
) - Courant number (
c
) - Velocity of upper layer (
v1
) - Velocity of upper-mid layer (
v2
) - Velocity of lower-mid layer (
v3
) - Velocity of lower layer (
v4
) - Source amplitude (
a
) - Source spread (
s
) - Source location in
$x$ given in cells (ox
) - Source location in
$x$ given in cells (oy
)
The program writes a file named wave-sim.txt
containing the 2D array,
Note that no dy
is required as the model is assumed to be isotropic, and all parameters are given in SI units unless otherwise stated. The boundaries are reflecting (
- Langtangen, H. P. (2013). A Primer on Scientific Programming with Python. Springer.