Skip to content

Commit

Permalink
Sync with miepython 2.5.3, fix several issues
Browse files Browse the repository at this point in the history
  • Loading branch information
TacHawkes committed Oct 28, 2023
1 parent 9a2d13b commit b07ac78
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 42 deletions.
42 changes: 23 additions & 19 deletions src/mie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -400,35 +400,39 @@ end
Figure out scattering function normalization.
# Parameters
- `a`: complex array of An coefficients
- `b`: complex array of Bn coefficients
- `m`: complex index of refraction of sphere
- `x`: dimensionless sphere size
- `norm`: symbol describing type of normalization
# Output
scaling factor needed for scattering function
"""
function normalization_factor(a, b, x; norm = :albedo)
function normalization_factor(m, x; norm = :albedo)
norm === :bohren && return 1 / 2
norm === :wiscombe && return 1.0

n = 1:length(a)
qext = 2 * sum(i -> (2i + 1) * (real(a[i]) + real(b[i])), n) / x^2

(norm === :a || norm === :albedo) && return * x^2 * qext)
if norm (:qsca, :scattering_efficiency)
return x * (π)
end

qsca = 2 * sum(i -> (2i + 1) * (abs2(a[i]) + abs2(b[i])), n) / x^2
qext, qsca, _, _ = mie(m, x)

(norm === :one || norm === :unity) && return (qsca * π * x^2)
if norm (:a, :albedo)
return x * * qext)
end

norm === :four_pi && return (qsca * x^2 / 4)
if norm (:one, :unity)
return x * * qsca)
end

(norm === :qsca || norm === :scattering_efficiency) && return * x^2)
norm === :four_pi && return x * (qsca / 4)

(norm === :qext || norm === :extinction_efficiency) && return (qsca * π * x^2 / qext)
if norm (:qext, :extinction_efficiency)
return x * (qsca * π / qext)
end

throw(
DomainError(
ArgumentError(
"Normalization must be one of :albedo (default), :one, :four_pi, :qext,
:qsca, :bohren or :wiscombe",
),
Expand Down Expand Up @@ -460,7 +464,7 @@ function mie_S1_S2(m, x, μ; norm = :albedo, use_threads = true)
S2 = Vector{ComplexF64}(undef, nangles)

nstop = length(a)
normalization = normalization_factor(a, b, x; norm)
normalization = normalization_factor(m, x; norm)
@batch minbatch = (use_threads ? 1 : typemax(Int)) for k = 1:nangles
pi_nm2 = 0.0
pi_nm1 = 1.0
Expand Down Expand Up @@ -745,16 +749,16 @@ function mie_phase_matrix(m, x, μ::AbstractVector; norm = :albedo)
m1 = abs2(s1[i])
m2 = abs2(s2[i])
s21 = real(0.5 * (s1[i] * s2_star + s2[i] * s1_star))
d21 = real(-0.5 * (s1[i] * s2_star - s2[i] * s1_star))
d21 = real(-0.5*im * (s1[i] * s2_star - s2[i] * s1_star))

phase[1, 1, i] = 0.5 * (m2 + m1)
phase[1, 2, i] = 0.5 * (m2 + m1)
phase[1, 2, i] = 0.5 * (m2 - m1)
phase[2, 1, i] = phase[1, 2, i]
phase[2, 2, i] = phase[1, 1, i]
phase[3, 3, i] = s21
phase[2, 4, i] = -d21
phase[3, 2, i] = d21
phase[3, 3, i] = s21
phase[3, 4, i] = -d21
phase[4, 3, i] = d21
phase[4, 4, i] = s21
end

return phase
Expand Down
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ using Test
include("suites/small.jl")
include("suites/perfectlyreflecting.jl")
include("suites/anglescattering.jl")
include("suites/phasematrix.jl")
include("suites/notebook.jl")
end
30 changes: 7 additions & 23 deletions test/suites/anglescattering.jl
Original file line number Diff line number Diff line change
Expand Up @@ -119,34 +119,18 @@ function test_i_par_i_per_01()
end
end

function test_mie_phase_matrix_basic()
m = 1.5 - im * 1.5
x = 2
μ = LinRange(-1, 1, 1000)

p = mie_phase_matrix(m, x, μ)
p11 = i_unpolarized(m, x, μ)

@test all(x -> isapprox(x...), zip(p[1, 1, :], p11))
end

function test_mie_phase_matrix_mu_scalar()
@test size(mie_phase_matrix(1.5, 2.0, 0.0)) == (4, 4)
end

function test_mie_phase_matrix_symmetry()
p = mie_phase_matrix(1.5, 2.0, LinRange(-1, 1, 10))

@test all(x -> isapprox(x...), zip(p[1, 2, :], p[2, 1, :]))
@test all(x -> isapprox(x...), zip(p[3, 4, :], -p[4, 2, :]))
function test_molecular_hydrogen()
m = 1.00013626
x = 0.0006403246172921872
mu = LinRange(-1, 1, 100)
ph = i_unpolarized(m, x, mu)
@test ph[2] 0.1169791 atol=1e-5
end

@testset "AngleScattering" begin
test_12_scatter_function()
test_13_unity_normalization()
test_i_unpolarized_01()
test_i_par_i_per_01()
test_mie_phase_matrix_basic()
test_mie_phase_matrix_mu_scalar()
test_mie_phase_matrix_symmetry()
test_molecular_hydrogen()
end
81 changes: 81 additions & 0 deletions test/suites/phasematrix.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
function test_mie_phase_matrix_basic()
m = 1.5 - im * 1.5
x = 2
μ = LinRange(-1, 1, 1000)

p = mie_phase_matrix(m, x, μ)
p00 = i_unpolarized(m, x, μ)

@test all(x -> isapprox(x...), zip(p[1, 1, :], p00))
end

function test_mie_phase_matrix_mu_scalar()
@test size(mie_phase_matrix(1.5, 2.0, 0.0)) == (4, 4)
end

function test_mie_phase_matrix_symmetry()
p = mie_phase_matrix(1.5, 2.0, LinRange(-1, 1, 10))

@test all(x -> isapprox(x...), zip(p[1, 2, :], p[2, 1, :]))
@test all(x -> isapprox(x...), zip(p[3, 4, :], -p[4, 3, :]))
end

function test_mie_phase_matrix_unity()
m = 1.5 - im * 1.5
x = 2
μ = LinRange(-1, 1, 1000)

p = mie_phase_matrix(m, x, μ)

@test all(
x -> isapprox(x...),
zip(p[1, 1, :] .^ 2, p[1, 2, :] .^ 2 + p[3, 3, :] .^ 2 + p[3, 4, :] .^ 2),
)
end

function test_mie_phase_matrix_bohren()
mm = [
000.00 0.100000E+01 0.000000E+00 0.100000E+01 0.000000E+00
009.00 0.785390E+00 -0.459811E-02 0.999400E+00 0.343261E-01
018.00 0.356897E+00 -0.458541E-01 0.986022E+00 0.160184E+00
027.00 0.766119E-01 -0.364744E+00 0.843603E+00 0.394076E+00
036.00 0.355355E-01 -0.534997E+00 0.686967E+00 -0.491787E+00
045.00 0.701845E-01 0.959953E-02 0.959825E+00 -0.280434E+00
054.00 0.574313E-01 0.477927E-01 0.985371E+00 0.163584E+00
063.00 0.219660E-01 -0.440604E+00 0.648043E+00 0.621216E+00
072.00 0.125959E-01 -0.831996E+00 0.203255E+00 -0.516208E+00
081.00 0.173750E-01 0.341670E-01 0.795354E+00 -0.605182E+00
090.00 0.124601E-01 0.230462E+00 0.937497E+00 0.260742E+00
099.00 0.679093E-02 -0.713472E+00 -0.717397E-02 0.700647E+00
108.00 0.954239E-02 -0.756255E+00 -0.394748E-01 -0.653085E+00
117.00 0.863419E-02 -0.281215E+00 0.536251E+00 -0.795835E+00
126.00 0.227421E-02 -0.239612E+00 0.967602E+00 0.795798E-01
135.00 0.543998E-02 -0.850804E+00 0.187531E+00 -0.490882E+00
144.00 0.160243E-01 -0.706334E+00 0.495254E+00 -0.505781E+00
153.00 0.188852E-01 -0.891081E+00 0.453277E+00 -0.226817E-01
162.00 0.195254E-01 -0.783319E+00 -0.391613E+00 0.482752E+00
171.00 0.301676E-01 -0.196194E+00 -0.962069E+00 0.189556E+00
180.00 0.383189E-01 0.000000E+00 -0.100000E+01 0.000000E+00
]

m = 1.55
x = 5.213
θ = LinRange(0, 180, 21)

μ = cosd.(θ)
p = mie_phase_matrix(m, x, μ, norm = :bohren)

@test all(x -> isapprox(x...), zip(θ, mm[:, 1]))
@test all(x -> isapprox(x...; atol=1e-3), zip(p[1, 1, :] / p[1, 1, 1], mm[:, 2]))
@test all(x -> isapprox(x...; atol=1e-3), zip(-p[1, 2, :] ./ p[1, 1, :], mm[:, 3]))
@test all(x -> isapprox(x...; atol=1e-3), zip(p[3, 3, :] ./ p[1, 1, :], mm[:, 4]))
@test all(x -> isapprox(x...; atol=1e-3), zip(p[4, 3, :] ./ p[1, 1, :], mm[:, 5]))
end

@testset "MiePhaseMatrix" begin
test_mie_phase_matrix_basic()
test_mie_phase_matrix_mu_scalar()
test_mie_phase_matrix_symmetry()
test_mie_phase_matrix_unity()
test_mie_phase_matrix_bohren()
end

0 comments on commit b07ac78

Please sign in to comment.