Rigid sphere scattering (Exterior)
Importing related packages
using BoundaryIntegralEquations # For BIEs
using LegendrePolynomials # For Legendre Polynomials
using SpecialFunctions # For Bessel functions
using IterativeSolvers # For gmres
using LinearAlgebra # For Diagonal
using Meshes # For 3d mesh plots
using Plots # For 2d plots
import GLMakie as wgl
Setting up constants
frequency = 100.0; # Frequency [Hz]
c = 343; # Speed up sound [m/s]
a = 1.0; # Radius of sphere_1m [m]
k = 2π*frequency/c; # Wavenumber
P₀ = 1.0; # Magnitude of planewave
Loading Mesh
Loading and visualizing the triangular (spherical) mesh
mesh_file = joinpath(dirname(pathof(BoundaryIntegralEquations)),"..","examples","meshes","sphere_1m_coarser");
mesh = load3dTriangularComsolMesh(mesh_file;physics_order=:disctrilinear)
Number of elements: 246
Number of unkowns: 738
Geometry defined by: BoundaryIntegralEquations.TriangularQuadratic{Float64}
Physics defined by: BoundaryIntegralEquations.DiscontinuousTriangularLinear{Float64}
Analytical Solution
The analytical solution of the scattering of a sphere by plane wave can be computed as ([14])
\[ p_\text{analytical}(r, \theta) = P_0\left(\exp(\mathrm{i}kr\cos(\theta)) - \sum_{n=1}^\infty \mathrm{i}^n(2n+1)\frac{j_n^{'}(ka)}{h_n^{'}(ka)}P_n(\cos(\theta))h_n(kr)\right),\]
where $j_n, h_n$ and $P_n$ are respectively the spherical Bessel function of the first kind, the Hankel function of the first kind and the Legendre polynomial of degree $n$. To make the implementation easier we define the following helper functions
dsp_j(n,z) = n/z*sphericalbesselj(n,z) - sphericalbesselj(n+1,z); # Derivative of j
dsp_y(n,z) = n/z*sphericalbessely(n,z) - sphericalbessely(n+1,z); # Derivative of y
sp_h(n,z) = sphericalbesselj(n,z) + im*sphericalbessely(n,z); # Hankel function (h)
dsp_h(n,z) = dsp_j(n,z) + im*dsp_y(n,z); # Derivative of h
Using the helper functions we can define the a function for the coefficients
c_n(n,ka) = (im)^n*(2n + 1)*(dsp_j(n,ka)./dsp_h(n,ka));
The total pressure as the sum of scattered and incident pressure
θ_analytical = collect(0:0.01:π); # Angles where the analytical solution will be evaluated
N_truncation = 50; # Truncation of the sum
p_s = P₀*sum(n -> -c_n(n,k*a) .* Pl.(cos.(θ_analytical), n) .* sp_h.(n,k*a), 0:N_truncation);
p_i = P₀*exp.(im*k*cos.(θ_analytical))
p_analytical = p_s + p_i;
Solution using the BEM
Computing incident pressure at the collocation points
pI = P₀*exp.(im*k*mesh.sources[3,:]);
Computing the BEM solution using dense matrices
Fp,_,Cp = assemble_parallel!(mesh,k,mesh.sources,n=2,m=2,progress=false);
Hp = Fp + Diagonal(1.0 .- Cp);
p_bem = gmres(Hp,pI;verbose=true);
=== gmres ===
rest iter resnorm
1 1 1.16e+01
1 2 3.00e+00
1 3 1.37e-01
1 4 7.54e-04
1 5 6.75e-05
1 6 5.90e-06
1 7 8.27e-08
Computing BEM solution using the FMM operator
Ff = FMMFOperator(mesh,k);
Hf = Ff + 0.5I;
p_fmm = gmres(Hf,pI;verbose=true);
=== gmres ===
rest iter resnorm
1 1 1.16e+01
1 2 3.00e+00
1 3 1.37e-01
1 4 8.80e-04
1 5 5.01e-05
1 6 1.13e-05
1 7 1.78e-07
Computing BEM solution using the H operator
Fh = HFOperator(mesh,k);
Hh = Fh + 0.5I;
p_h = gmres(Hh,pI;verbose=true);
[ Info: Assembling HMatrix on 4 threads
=== gmres ===
rest iter resnorm
1 1 1.16e+01
1 2 3.00e+00
1 3 1.37e-01
1 4 8.80e-04
1 5 5.01e-05
1 6 1.13e-05
1 7 1.78e-07
Plotting solution
For plotting purposes we must order the solution w.r.t the angles
surface_angles = acos.(mesh.sources[3,:]/a);
perm = sortperm(surface_angles);
Plotting real part of pressure
plot(θ_analytical, real.(p_analytical),label="Analytical",linewidth=2)
xlabel!("Angle (rad)"); ylabel!("re(p)");
plot!(surface_angles[perm],real.(p_bem[perm]),label="BEM",linestyle=:dash,linewidth=2)
plot!(surface_angles[perm],real.(p_fmm[perm]),label="FMM",linestyle=:dash,linewidth=2)
plot!(surface_angles[perm],real.(p_h[perm]),label="H-matrix",linestyle=:dash,linewidth=2)
Plotting imaginary part of pressure
plot(θ_analytical, imag.(p_analytical),label="Analytical",linewidth=2)
xlabel!("Angle (rad)"); ylabel!("im(p)");
plot!(surface_angles[perm],imag.(p_bem[perm]),label="BEM",linestyle=:dash,linewidth=2)
plot!(surface_angles[perm],imag.(p_fmm[perm]),label="FMM",linestyle=:dash,linewidth=2)
plot!(surface_angles[perm],imag.(p_h[perm]),label="H-matrix",linestyle=:dash,linewidth=2)
Plotting absolute pressure values
plot(θ_analytical, abs.(p_analytical),label="Analytical",linewidth=2)
xlabel!("Angle (rad)"); ylabel!("|p|");
plot!(surface_angles[perm],abs.(p_bem[perm]),label="BEM",linestyle=:dash,linewidth=2)
plot!(surface_angles[perm],abs.(p_fmm[perm]),label="FMM",linestyle=:dash,linewidth=2)
plot!(surface_angles[perm],abs.(p_h[perm]),label="H-matrix",linestyle=:dash,linewidth=2)
Plotting the solution on the sphere. Note that the mesh is plotted as linear due to the underlying library used, not because the mesh itself is linear.
wgl.set_theme!(resolution=(600, 600))
data_mesh,data_viz = create_vizualization_data(mesh,p_fmm)
fig, ax, hm = viz(data_mesh;showfacets=true, color=abs.(data_viz))
wgl.Colorbar(fig[1,2],label="|p|");
Bibliography
- [14]
- F. Ihlenburg. Finite Element Analysis of Acoustic Scattering (Springer, 1998).
This page was generated using Literate.jl.