Wave equation simulation

Date: 2023-08-01 ๏ฝœ Author: Jason Eveleth

Table of Contents

Inspiration

Imagine your worst enemy is playing a constant frequency in the center of her room. You're allowed to put speakers (which don't take up space) wherever you want in the room. The question is, what's the best place to put them and what should they play?

To be fair, this is not the question that I'll be answering in this post, but it was the inspiration. We first simplify the problem into 2D so your enemy is now vibrating a surface with constant frequency. To simulate this problem, we need to solve the wave equation, which I do in this post.

At first, I tried to figure out the finite difference equations, but I got stuck. Then, I looked it up and I found this wonderful blog post. I've rederived the equations to make sure I believed it and I wrote the code in Julia, which you can find it on GitHub. My first attempt at figuring out the finite differences is in the Python notebook, and the final code is in simulation.jl.

In action

The rederivation

See calculus notation for notation. The wave equation is

Dttu=c2(Dxxu+Dyyu)D_{tt}u = c^2 ( D_{xx}u + D_{yy}u)

First, we figure out what the finite difference wave equation looks like. Since we have a second time derivative, we need to keep 2 past states to calculate the difference in the first derivative. Look at this picture (u0,i,ju_{0,i,j} is the newest state)

Mode of action of the discretized version of the differential operator for the solution of the wave equation

Let's do the time derivative first.

Dtu1,i,j=ฮ”tu1,i,jdt=u1,i,jโˆ’u2,i,jdtD_tu_{1,i,j} = \frac{\Delta_t u_{1,i,j}}{dt} = \frac{u_{1,i,j} - u_{2, i, j}}{dt}

So,

Dttu1,i,j=ฮ”tDtu1,i,jdt=u0,i,jโˆ’u1,i,jdtโˆ’u1,i,jโˆ’u2,i,jdtdt=u0,i,jโˆ’2u1,i,j+u2,i,j(dt)2D_{tt}u_{1,i,j} = \frac{\Delta_t D_t u_{1,i,j}}{dt}=\frac{\frac{u_{0,i,j} - u_{1, i, j}}{dt}-\frac{u_{1,i,j} - u_{2, i, j}}{dt}}{dt} = \frac{u_{0,i,j}-2u_{1,i,j}+u_{2,i,j}}{(dt)^2}

Next, we do space derivatives (ignoring c2c^2 for now),

Dxxu1,i,j+Dyyu1,i,j=ฮ”xDxu1,i,jdx+ฮ”yDyu1,i,jdy=u1,iโˆ’1,jโˆ’2u1,i,j+u1,i+1,j(dx)2+u1,i,jโˆ’1โˆ’2u1,i,j+u1,i,j+1(dy)2 \begin{align*} D_{xx}u_{1,i,j} &+ D_{yy}u_{1,i,j} = \frac{\Delta_x D_x u_{1,i,j}}{dx} + \frac{\Delta_y D_y u_{1,i,j}}{dy}\\ &= \frac{u_{1,i-1,j} - 2u_{1,i,j} + u_{1,i+1,j}}{(dx)^2} + \frac{u_{1,i,j-1} - 2u_{1,i,j} + u_{1,i,j+1}}{(dy)^2} \end{align*}

Returning to the wave equation,

Dttu=c2(Dxxu+Dyyu)u0,i,jโˆ’2u1,i,j+u2,i,j(dt)2=c2(u1,iโˆ’1,jโˆ’2u1,i,j+u1,i+1,j(dx)2+u1,i,jโˆ’1โˆ’2u1,i,j+u1,i,j+1(dy)2)u0,i,j=2u1,i,jโˆ’u2,i,j+c2(dt)2(u1,iโˆ’1,jโˆ’2u1,i,j+u1,i+1,j(dx)2+u1,i,jโˆ’1โˆ’2u1,i,j+u1,i,j+1(dy)2) \begin{align*} D_{tt}u &= c^2 ( D_{xx}u + D_{yy}u)\\ \frac{u_{0,i,j}-2u_{1,i,j}+u_{2,i,j}}{(dt)^2} &= c^2\left(\frac{u_{1,i-1,j} - 2u_{1,i,j} + u_{1,i+1,j}}{(dx)^2} + \frac{u_{1,i,j-1} - 2u_{1,i,j} + u_{1,i,j+1}}{(dy)^2}\right)\\ u_{0,i,j} &= 2u_{1,i,j} - u_{2,i,j} +c^2 (dt)^2\left( \frac{u_{1,i-1,j} - 2u_{1,i,j} + u_{1,i+1,j}}{(dx)^2} + \frac{u_{1,i,j-1} - 2u_{1,i,j} + u_{1,i,j+1}}{(dy)^2}\right) \end{align*}

If we assume dx=dydx = dy and ฮฑ=c2(dt)2(dx)2\alpha = \frac{c^2 (dt)^2}{(dx)^2} then

u0,i,j=2u1,i,jโˆ’u2,i,j+ฮฑ(u1,iโˆ’1,j+u1,i,jโˆ’1โˆ’4u1,i,j+u1,i+1,j+u1,i,j+1)u_{0,i,j} = 2u_{1,i,j} - u_{2,i,j} +\alpha\left( u_{1,i-1,j}+u_{1,i,j-1} - 4u_{1,i,j} + u_{1,i+1,j} + u_{1,i,j+1}\right)

There are no u0,_,_u_{0,\_,\_} on the RHS. Thus, every value in the newest level can be calculated by the ones in previous levels.

We deal with the boundary by only calculating u[0,1:lx,1:ly], and leaving the rest 0. So shifts are calculated like so: u[1,0:lx-2,1:ly].

Note: this is actually Verlet integration (a trick for solving for the next state in terms of the finite differences and the second derivatives).

Implementation details

We can play a frequency by resetting the value of a u0,i,ju_{0,i,j} after the step to the value of a sine wave at the time. We can make a water droplet by setting part of the u0,i,ju_{0,i,j} layer to a negative gaussian at a certain time step. This is achieved with put_drop!() and play_noise!() functions.

ยฉ Jason Eveleth 2023 ยท Powered by Franklin.jl ยท Last modified: December 31, 2024 Page Source