Last post, I wrote some doodle work on solving the wave equation under FEM framework. And we did not consider the boundary condition, since the equation assumes valid for all plane. Now if truncated, PML is a way to save it, just with tiny modification on our previous work.

Formulation is not as simple as frequency domain using a trivial transformation to introduce absorption term. We need to use ifft to transform our Helmholtz equation back to time domain.

Think about equation:

using Laplace transform

Thus we got Helmholtz, is complex.

making coordinate transform as we do with Helmholtz:

with conductivity , which is positive outside domain and vanish inside.

Extend onto transformed space,

The transforming back,

means , therefore

where and , . Initial as 0.

Using finite difference is acceptable. Central scheme with time, and work carefully with gradient on spatial grid.

Or use FEM on spatial and RK4 for time integration. It should be fast on constructing the matrices if time-independent. Then it would be easy to calculate

each step involves 4 calls on the function , and each call involves 10 sparse-matrix-dense-vector multiplication, timing takes 0.05 seconds each for a matrix size of 18000 or so. That is about 12 seconds for one time step!! Unless we can find a way to reduce the calculations.

Hooray! By profiling the calculations, multiplication is just too fast and mldivide is taking most of time. But we know one thing, everything is going to be applied the same operation mldivide at last, do it at one pass with reduce the overhead at each round, the real calculation time would be only 1e-3 or so, but overhead will make it 1e-1 somehow.

Another thing is calculating the vector-mass matrix like

It seems taking twice the timing than just stiffness or mass. However, we know one thing, as a sparse matrix COO-format : are fixed during all calculations like this, then avoiding getting extra work will make things move faster.

Update: examples are included in femex/example/PML on github. Performance is reasonable.

Problematic part: The previous overhead argument is kind of wrong in Matlab, horzcat creates a pretty large copy of the input, that will allocates lots of memory in advance.

Another thing is the ode45, it stores all solutions. That is a large cost, and porting them into plot function also takes a lot of time.

Workaround: try to write a function in C using GSL to make this faster, or write some function with C to avoid storing the solution. Or simply add a callback..