Skip to content

Commit e6724e0

Browse files
committed
changed diff_scat_intensity_complex_medium() to output cross-section*k^2
This changes the nondimensionalizing factor from d^2 to |k|^2. Outputs must now be multiplied by 1/|k|^2 to recover dimensional cross-sections, which is aligned with how other cross-section functions return their values
1 parent f9eaea7 commit e6724e0

File tree

2 files changed

+22
-36
lines changed

2 files changed

+22
-36
lines changed

pymie/mie.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,11 +1161,8 @@ def diff_scat_intensity_complex_medium(m, x, thetas, kd, phis=None,
11611161
11621162
Notes
11631163
-----
1164-
To get dimensional cross-sections, multiply by d^2, where d is the distance
1165-
at which the differential cross-sections are calculated. To compare
1166-
differential cross-sections for non-absorbing media and the far-field to
1167-
those reported by calc_ang_scat(), which are nondimensionalized by k^2,
1168-
multiply the results from this function by kd^2.
1164+
To get dimensional cross-sections, multiply by 1/|k|^2 (1/np.abs(k)**2),
1165+
where k is the wavevector in media.
11691166
11701167
References
11711168
----------
@@ -1217,8 +1214,11 @@ def diff_scat_intensity_complex_medium(m, x, thetas, kd, phis=None,
12171214
I_1 = (np.abs(vec_scat_amp_1)**2)*factor # par or x
12181215
I_2 = (np.abs(vec_scat_amp_2)**2)*factor # perp or y
12191216

1220-
# the intensities should be real
1221-
return np.array([I_1.real, I_2.real])
1217+
# the intensities should be real. We multiply by |kd|^2 so that the
1218+
# resulting nondimensional cross-sections can be dimensionalized by
1219+
# multiplying by 1/|k|^2 (just as with cross-sections returned by other
1220+
# functions)
1221+
return np.array([I_1.real, I_2.real])*np.abs(kd)**2
12221222

12231223
def integrate_intensity_complex_medium(dscat, thetas, kd,
12241224
phi_min=0.0,
@@ -1270,8 +1270,8 @@ def integrate_intensity_complex_medium(dscat, thetas, kd,
12701270
12711271
Notes
12721272
-----
1273-
Returns dimensionless cross-sections. Multiply these by 1/k^2
1274-
and take the real part to recover the dimensional cross-sections.
1273+
Returns dimensionless cross-sections. Multiply these by 1/|k|^2
1274+
(1/np.abs(k)**2) to recover the dimensional cross-sections.
12751275
12761276
"""
12771277
# check that if phis is specified, both thetas and phis are given as 2D
@@ -1293,11 +1293,8 @@ def integrate_intensity_complex_medium(dscat, thetas, kd,
12931293
# because by the time we use it, we have already integrated over theta
12941294
phis = phis[..., 0, :]
12951295

1296-
# Multiply differential cross-sections by (k*distance)^2 (generally
1297-
# distance is radius of particle) because this is k^2*(integration
1298-
# factor over solid angles) (see eq. 4.58 in Bohren and Huffman).
1299-
dsigma_1 = dscat[0] * kd**2
1300-
dsigma_2 = dscat[1] * kd**2
1296+
dsigma_1 = dscat[0]
1297+
dsigma_2 = dscat[1]
13011298

13021299
if not cartesian:
13031300
if phis is not None:

pymie/tests/test_mie.py

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -496,21 +496,10 @@ def test_differential_cross_section():
496496
incident_vector,
497497
cartesian=False)
498498

499-
# calc_ang_scat returns dimensionless differential cross-sections (times
500-
# k^2). As noted in diff_scat_intensity_complex_medium(), this function
501-
# returns dimensionless values (scaled by k^2) muliplied by a factor of
502-
# 1/kd^2 for a non-absorbing medium. Therefore the
503-
# diff_scat_intensity_complex_medium() results are the dimensional
504-
# cross-sections scaled by 1/d^2, where d is the distance at which the
505-
# calculation is done. In short, both functions return dimensionless
506-
# cross-sections, but the ones returned by
507-
# diff_scat_intensity_complex_medium() need to be multiplied by a factor of
508-
# kd^2 to compare them to those of calc_ang_scat()
509-
#
510499
# since both of these functions rely on the same routine to calculate the
511500
# amplitude scattering matrix, they should give results to within
512501
# floating-point precision
513-
assert_allclose(I_parperp*kd**2, I_parperp_cad, rtol=1e-14)
502+
assert_allclose(I_parperp, I_parperp_cad, rtol=1e-14)
514503

515504

516505
def test_cross_section_complex_medium():
@@ -556,7 +545,7 @@ def test_cross_section_complex_medium():
556545
I_parperp = mie.diff_scat_intensity_complex_medium(m, x, theta, rho_scat)
557546
cscat_exact = mie.integrate_intensity_complex_medium(I_parperp, theta,
558547
rho_scat)[0]
559-
cscat_exact_dimensional = (cscat_exact/k**2).to("um^2")
548+
cscat_exact_dimensional = (cscat_exact/np.abs(k)**2).to("um^2")
560549

561550
# check that intensity equations without the asymptotic form of the spherical
562551
# Hankel equations (because they simplify when the fields are multiplied by
@@ -603,12 +592,12 @@ def test_cross_section_complex_medium():
603592
near_field=True)
604593
cscat_exact2 = mie.integrate_intensity_complex_medium(I_parperp, theta,
605594
rho_scat)[0]
595+
cscat_exact2_dimensional = (cscat_exact2/np.abs(k)**2).to("um^2")
606596

607-
assert_allclose((cscat_exact2/k**2).to("um^2").magnitude,
608-
cscat_sudiarta2.to('um^2').magnitude, rtol=1e-4)
609-
assert_allclose((cscat_exact2/k**2).to('um^2').magnitude,
610-
cscat_fu2.to('um^2').magnitude, rtol=1e-4)
611-
597+
assert_allclose(cscat_exact2_dimensional.magnitude,
598+
cscat_sudiarta2.to("um^2").magnitude, rtol=1e-4)
599+
assert_allclose(cscat_exact2_dimensional.magnitude,
600+
cscat_fu2.to("um^2").magnitude, rtol=1e-4)
612601

613602
# test that the cross sections calculated with the full Mie solutions
614603
# match the far-field Mie solutions when the matrix absorption is close to 0
@@ -623,7 +612,7 @@ def test_cross_section_complex_medium():
623612

624613
cscat_exact3 = mie.integrate_intensity_complex_medium(I_parperp, theta,
625614
rho_scat)[0]
626-
cscat_exact3_dimensional = (cscat_exact3/k**2).to("um^2")
615+
cscat_exact3_dimensional = (cscat_exact3/np.abs(k)**2).to("um^2")
627616

628617
# With far-field Mie solutions
629618
cscat_mie3 = mie.calc_cross_sections(m, x)[0]
@@ -660,7 +649,7 @@ def test_multilayer_complex_medium():
660649
cscat_imag = mie.integrate_intensity_complex_medium(I_parperp, angles,
661650
kd)[0]
662651

663-
cscat_imag_dimensional = (cscat_imag/k**2).to("nm^2")
652+
cscat_imag_dimensional = (cscat_imag/np.abs(k)**2).to("nm^2")
664653

665654
# check that intensity equations without the asymptotic form of the spherical
666655
# Hankel equations (because they simplify when the fields are multiplied by
@@ -763,7 +752,7 @@ def test_diff_scat_intensity_complex_medium_cartesian():
763752
# Because of the way this test is done (using a 2D array of angles
764753
# for theta), we don't end up with a wavelength axis for I_parperp. Have
765754
# to squeeze to compare.
766-
assert_array_almost_equal(I_xy_mag.squeeze(), I_par_perp_mag, decimal=16)
755+
assert_allclose(I_xy_mag.squeeze(), I_par_perp_mag, rtol=1e-15)
767756

768757
def test_integrate_intensity_complex_medium_cartesian():
769758
'''
@@ -797,7 +786,7 @@ def test_integrate_intensity_complex_medium_cartesian():
797786
cscat_xy = mie.integrate_intensity_complex_medium(I_xy, thetas, kd,
798787
cartesian=True,
799788
phis=phis)[0]
800-
cscat_xy_dimensional = (cscat_xy/k**2).to("nm^2")
789+
cscat_xy_dimensional = (cscat_xy/np.abs(k)**2).to("nm^2")
801790

802791
# check that intensity equations without the asymptotic form of the spherical
803792
# Hankel equations (because they simplify when the fields are multiplied by

0 commit comments

Comments
 (0)