Exact cylindrical harmonic series solution for a time-harmonic plane wave diffracting around a rigid (sound-hard) circular cylinder in 2D.
This demo computes the exact analytical solution for a plane wave scattering off a rigid circular cylinder in two dimensions. "Rigid" means the cylinder is perfectly immovable: the fluid particle velocity normal to the surface must be zero, which via Euler’s equation requires the normal pressure gradient to vanish. Mathematically, this is a Neumann boundary condition—zero normal derivative of pressure at the surface [1, 2].
The total pressure field outside the cylinder is the sum of two parts: p = pinc + pscat, where pinc is the incident plane wave (propagating in the +x direction) and pscat is the scattered wave produced by the cylinder. The checkboxes above let you view each component independently.
The solution uses a classical technique [1, Ch. 8]: expand the incoming plane wave as a sum of cylindrical harmonics (Bessel functions times cosines) using the Jacobi–Anger identity, then match each term with an outgoing cylindrical wave (a Hankel function) whose amplitude is chosen so the boundary condition is satisfied [2, Ch. 2]. Because each harmonic order n can be solved independently, the whole problem reduces to evaluating a finite sum of special functions.
The key parameter is ka = 2πa/λ, which compares the cylinder circumference to the acoustic wavelength [3]:
The Scattering terms slider controls how many terms are kept in the scattered wave series. Using too few produces visible artifacts, especially at higher frequencies. The incident plane wave is always evaluated exactly. The |p| display mode shows the pressure amplitude (modulus of the complex pressure field), which is constant in time but varies spatially.
For time-harmonic acoustic waves at angular frequency ω, the pressure satisfies the Helmholtz equation:
∇²p + k²p = 0, k = ω/cwhere c is the sound speed and k is the wavenumber. In polar coordinates (r, θ), solutions separable in r and θ take the form Zn(kr) cos(nθ) or Zn(kr) sin(nθ), where Zn is any Bessel function of order n.
A plane wave propagating in the +x direction has the spatial part pinc = eikx = eikr cosθ. The Jacobi–Anger identity expands this into cylindrical harmonics [1, Ch. 7]:
eikr cosθ = ∑n=0∞ εn in Jn(kr) cos(nθ)where Jn is the Bessel function of the first kind of order n, and εn is the Neumann factor: ε0 = 1, εn = 2 for n ≥ 1. Only cosine terms appear because the incident wave and cylinder geometry are symmetric about the x-axis.
The scattered field must consist of outgoing waves at infinity, represented by Hankel functions of the first kind Hn(1). (Note: this derivation uses the e−iωt time convention, under which Hn(1), with asymptotic behavior e+ikr/√r, represents outgoing waves satisfying the Sommerfeld radiation condition. Texts using e+iωt would use Hn(2) instead.)
pscat = ∑n=0∞ εn in An Hn(1)(kr) cos(nθ)The rigid (Neumann) boundary condition ∂p/∂r = 0 at r = a requires, for each order n independently:
εn in [Jn′(ka) + An Hn(1)′(ka)] = 0Solving for the scattering coefficient:
An = −Jn′(ka) / Hn(1)′(ka)Combining the incident and scattered contributions:
p(r,θ) = ∑n=0N εn in [Jn(kr) + An Hn(1)(kr)] cos(nθ)The animated display shows Re[p(r,θ) e−iωt] at each time step, where ωt advances continuously. The modulus display shows |p(r,θ)|, which is constant in time.
Implementation note: In the demo, the incident plane wave is evaluated directly as eikx (a single cosine and sine per pixel) rather than via the Jacobi–Anger series expansion. This avoids truncation artifacts in the plane wave at high ka, where many terms would be needed for the series to converge far from the cylinder. The N-term series is used only for the scattered wave, which converges rapidly at N ≈ ⌈ka⌉ + 10. The total field computed is:
p = eikx + ∑n=0N−1 εn in An Hn(1)(kr) cos(nθ)which is mathematically equivalent to the combined form above.
Derivatives of any cylindrical Bessel function Zn (whether Jn, Yn, or Hn(1)) are computed via the recurrence [4, §9.1.27]:
Zn′(z) = Zn−1(z) − (n/z) Zn(z)For n = 0: Z0′(z) = −Z1(z). Since Hn(1) = Jn + iYn, the derivative Hn(1)′ = Jn′ + iYn′, making An a complex number computed via complex division.
The demo computes Jn(x) and Yn(x) for integer order n and real argument x without external libraries. Seed values J0, J1, Y0, Y1 are computed from rational polynomial approximations tabulated in Abramowitz & Stegun [4, §9.4]. Higher orders use:
The series converges rapidly because the scattering coefficients An → 0 for n ≫ ka (the numerator Jn′(ka) vanishes while the denominator grows). A safe truncation is N ≈ ⌈ka⌉ + 10 [1, Ch. 8]. The demo lets you reduce N below this to observe convergence artifacts. For real-time performance, Bessel values Jn(kr), Yn(kr) are precomputed on a radial lookup table of 512 bins, and cos(nθ) is evaluated via Chebyshev recurrence rather than repeated trigonometric calls.
References