Exemplo n.º 1
0
    def _calc_scat_matrix(self, scatterer, schema):
        if isinstance(scatterer, Sphere):
            scat_coeffs = self._scat_coeffs(scatterer, schema.optics)

            # TODO: actually use (rather than ignore) the phi
            scat_matrs = [mieangfuncs.asm_mie_far(scat_coeffs, theta) for
                          theta, phi in schema.positions_theta_phi()]
            return np.array(scat_matrs)
        else:
            raise TheoryNotCompatibleError(self, scatterer)
Exemplo n.º 2
0
 def massage_into_bh_form(asm):
     S2, S3, S4, S1 = np.ravel(asm)
     S11 = 0.5 * (abs(asm)**2).sum()
     S12 = 0.5 * (abs(S2)**2 - abs(S1)**2)
     S33 = real(S1 * conj(S2))
     S34 = imag(S2 * conj(S1))
     deg_of_pol = -S12/S11
     # normalization factors: see comment lines 40-44 on p. 479
     asm_fwd = mieangfuncs.asm_mie_far(asbs, 0.)
     S11_fwd = 0.5 * (abs(asm_fwd)**2).sum()
     results = np.array([S11/S11_fwd, deg_of_pol, S33 / S11, S34 / S11])
     return results
Exemplo n.º 3
0
    def _calc_scat_matrix(self, scatterer, schema):
        if isinstance(scatterer, Sphere):
            scat_coeffs = self._scat_coeffs(scatterer, schema.optics)

            # TODO: actually use (rather than ignore) the phi
            scat_matrs = [
                mieangfuncs.asm_mie_far(scat_coeffs, theta)
                for theta, phi in schema.positions_theta_phi()
            ]
            return np.array(scat_matrs)
        else:
            raise TheoryNotCompatibleError(self, scatterer)
Exemplo n.º 4
0
    def _raw_scat_matrs(self, scatterer, pos, medium_wavevec, medium_index):
        '''
        Returns far-field amplitude scattering matrices (with theta and phi
        dependence only) -- assume spherical wave asymptotic r dependence
        '''
        if self._can_handle(scatterer):
            scat_coeffs = self._scat_coeffs(
                scatterer, medium_wavevec, medium_index)

            # In the mie solution the amplitude scattering matrix is
            # independent of phi
            return [mieangfuncs.asm_mie_far(scat_coeffs, theta)
                    for r, theta, phi in pos.T]
        else:
            raise TheoryNotCompatibleError(self, scatterer)
Exemplo n.º 5
0
def test_mie_amplitude_scattering_matrices():
    '''
    Test calculation of Mie amplitude scattering matrix elements.
    We will check the following:
        far-field matrix elements (direct comparison with [Bohren1983]_)
        near-field matrix for kr ~ 10 differs from far-field result
        near-field matrix for kr ~ 10^4 is close to far-field result

    While radiometric quantities (such as cross sections) implicitly test
    the Mie scattering coefficients, they do not involve any angular
    quantities.
    '''

    # scattering units
    m = 1.55
    x = 2. * pi * 0.525 / 0.6328

    asbs = miescatlib.scatcoeffs(m, x, miescatlib.nstop(x))
    amp_scat_mat = mieangfuncs.asm_mie_far(asbs, theta)
    amp_scat_mat_asym = mieangfuncs.asm_mie_fullradial(asbs, np.array([kr_asym,
                                                                       theta,
                                                                       phi]))
    amp_scat_mat_near = mieangfuncs.asm_mie_fullradial(asbs, np.array([kr,
                                                                      theta,
                                                                      phi]))

    # gold results directly from B/H p.482.
    location = os.path.split(os.path.abspath(__file__))[0]
    gold_name = os.path.join(location, 'gold',
                             'gold_mie_scat_matrix')
    with open(gold_name + '.yaml') as gold_file:
        gold_dict = yaml.safe_load(gold_file)
    
    gold = np.array([gold_dict['S11'], gold_dict['pol'],
                     gold_dict['S33'], gold_dict['S34']])


    # B/H gives real scattering matrix elements, which are related
    # to the amplitude scatering elements.  See p. 65.
    def massage_into_bh_form(asm):
        S2, S3, S4, S1 = np.ravel(asm)
        S11 = 0.5 * (abs(asm)**2).sum()
        S12 = 0.5 * (abs(S2)**2 - abs(S1)**2)
        S33 = real(S1 * conj(S2))
        S34 = imag(S2 * conj(S1))
        deg_of_pol = -S12/S11
        # normalization factors: see comment lines 40-44 on p. 479
        asm_fwd = mieangfuncs.asm_mie_far(asbs, 0.)
        S11_fwd = 0.5 * (abs(asm_fwd)**2).sum()
        results = np.array([S11/S11_fwd, deg_of_pol, S33 / S11, S34 / S11])
        return results

    # off-diagonal elements should be zero
    assert_allclose(np.ravel(amp_scat_mat)[1:3], np.zeros(2))

    # check far-field computation
    assert_allclose(massage_into_bh_form(amp_scat_mat), gold,
                    rtol = 1e-5)

    # check asymptotic behavior of near field matrix
    asym = massage_into_bh_form(amp_scat_mat_asym)
    assert_allclose(asym, gold, rtol = 1e-4, atol = 5e-5)

    # check that the near field is different
    try:
        assert_allclose(amp_scat_mat, amp_scat_mat_near)
    except AssertionError:
        pass
    else:
        raise AssertionError("Near-field amplitude scattering matrix " +
                             "suspiciously close to far-field result.")