Shapes quick-start gallery

TransitionMatrices.jl handles several scatterer families. This gallery defines one of each, computes its T-matrix, and reports the basic far-field efficiencies \(Q_\text{sca}\), \(Q_\text{ext}\), the asymmetry parameter \(g\) and the single-scattering albedo \(\omega\).

The axisymmetric shapes (spheroid, cylinder, Chebyshev particle) use the default EBCM solver via calc_T; the N-fold prism is not axisymmetric, so it uses the IITM solver.

begin
    import Pkg
    Pkg.activate(@__DIR__)
    Pkg.develop(; path = dirname(@__DIR__))
    Pkg.instantiate()
    using TransitionMatrices, Plots
end

Define the shapes

All at wavelength λ = 2π (so the size parameter equals the radius) and the same refractive index m = 1.5 + 0.02im.

begin
    λ = 2π
    m = 1.5 + 0.02im
    shapes = (
        spheroid  = TransitionMatrices.Spheroid{Float64, ComplexF64}(2.0, 1.0, m),
        cylinder  = TransitionMatrices.Cylinder{Float64, ComplexF64}(1.0, 2.0, m),
        chebyshev = TransitionMatrices.Chebyshev{Float64, ComplexF64}(1.0, 0.1, 4, m),
        prism6    = TransitionMatrices.Prism(6, 1.0, 2.0, m),
    )
end
(spheroid = Spheroid{Float64, ComplexF64}(2.0, 1.0, 1.5 + 0.02im), cylinder = Cylinder{Float64, ComplexF64}(1.0, 2.0, 1.5 + 0.02im), chebyshev = Chebyshev{Float64, ComplexF64}(1.0, 0.1, 4, 1.5 + 0.02im), prism6 = Prism{6, Float64, ComplexF64}(1.0, 2.0, 1.5 + 0.02im))

Compute and tabulate

calc_T auto-converges the axisymmetric shapes; the prism uses a fixed-order IITM solve. Pluto renders the resulting vector of named tuples as a table.

begin
    Tmatrix(s) = s isa TransitionMatrices.Prism ?
        transition_matrix(s, λ, IITM(8, 12, 24, 24)) : calc_T(s, λ)

    summary = map(collect(pairs(shapes))) do (name, s)
        T = Tmatrix(s)
        (; shape = name,
            Qsca = round(calc_Csca(T, λ); digits = 4),
            Qext = round(calc_Cext(T, λ); digits = 4),
            g = round(asymmetry_parameter(T, λ); digits = 4),
            ω = round(albedo(T); digits = 4))
    end
end
4-element Vector{@NamedTuple{shape::Symbol, Qsca::Float64, Qext::Float64, g::Float64, ω::Float64}}:
 (shape = :spheroid, Qsca = 6.6711, Qext = 7.5993, g = 0.5339, ω = 0.8779)
 (shape = :cylinder, Qsca = 1.3708, Qext = 1.6609, g = 0.2721, ω = 0.8254)
 (shape = :chebyshev, Qsca = 0.6613, Qext = 0.8415, g = 0.2004, ω = 0.7858)
 (shape = :prism6, Qsca = 0.9603, Qext = 1.1905, g = 0.239, ω = 0.8066)

Compare the efficiencies

let
    names = String.(getindex.(summary, :shape))
    bar(names, [getindex.(summary, :Qsca) getindex.(summary, :Qext)];
        label = ["Qsca" "Qext"], ylabel = "efficiency", legend = :topright,
        title = "far-field efficiencies by shape", size = (680, 380))
end

Which solver?

  • Spheroid / Cylinder / Chebyshev — axisymmetric: EBCM (calc_T). For high-aspect spheroids add the stabilized path, Iterative(EBCM; stable=true).

  • Prism / arbitrary 3-D — not axisymmetric: IITM (IITM(nₘₐₓ, Nr, Nϑ, Nφ)).

  • For wavelength / refractive-index sweeps of an axisymmetric shape, see the Sh-matrix examples (ShMatrix, prepare_sh).