コード例 #1
0
    def spherical_wave_expansion(self, particle, layer_system):
        """Regular spherical wave expansion of the wave including layer system response, at the locations of the
        particles.

        Args:
            particle (smuthi.particles.Particle):    particle relative to which the swe is computed
            layer_system (smuthi.layer.LayerSystem): stratified medium

        Returns:
            regular smuthi.field_expansion.SphericalWaveExpansion object
        """
        virtual_particle = part.Particle(position=self.position,
                                         l_max=1,
                                         m_max=1)
        wd = pc.direct_coupling_block(vacuum_wavelength=self.vacuum_wavelength,
                                      receiving_particle=particle,
                                      emitting_particle=virtual_particle,
                                      layer_system=layer_system)
        wr = pc.layer_mediated_coupling_block(
            vacuum_wavelength=self.vacuum_wavelength,
            receiving_particle=particle,
            emitting_particle=virtual_particle,
            layer_system=layer_system,
            k_parallel=self.k_parallel)
        k = self.angular_frequency() * layer_system.refractive_indices[
            layer_system.layer_number(particle.position[2])]
        swe = fldex.SphericalWaveExpansion(k=k,
                                           l_max=particle.l_max,
                                           m_max=particle.m_max,
                                           kind='regular',
                                           reference_point=particle.position)
        swe.coefficients = np.dot(
            wd + wr,
            self.outgoing_spherical_wave_expansion(layer_system).coefficients)
        return swe
コード例 #2
0
def test_w_against_wr():
    coord.set_default_k_parallel(wl, [0, 0.8, 0.8 - 0.1j, 2.1 - 0.1j, 2.1, 7],
                                 2e-3)
    laysys_air_1 = lay.LayerSystem(thicknesses=[0, 0],
                                   refractive_indices=[1, 1])
    laysys_air_2 = lay.LayerSystem(thicknesses=[0, 250, 0],
                                   refractive_indices=[1, 1, 1])

    part1 = part.Sphere(position=[100, -100, 200],
                        refractive_index=1.7,
                        radius=100,
                        l_max=2,
                        m_max=2)
    part2 = part.Sphere(position=[-100, 200, 400],
                        refractive_index=1.7,
                        radius=100,
                        l_max=2,
                        m_max=2)

    w_air_1 = coup.direct_coupling_block(wl, part1, part2, laysys_air_1)
    wr_air_2 = coup.layer_mediated_coupling_block(wl, part1, part2,
                                                  laysys_air_2)

    error = wr_air_2 - w_air_1
    np.testing.assert_almost_equal(wr_air_2, w_air_1, decimal=4)
コード例 #3
0
ファイル: linear_system.py プロジェクト: shepherdYoung/smuthi
    def __init__(self,
                 vacuum_wavelength,
                 particle_list,
                 layer_system,
                 k_parallel='default'):

        SystemMatrix.__init__(self, particle_list)
        coup_mat = np.zeros(self.shape, dtype=complex)
        sys.stdout.write('Coupling matrix memory footprint: ' +
                         coup.size_format(coup_mat.nbytes) + '\n')
        sys.stdout.flush()
        for s1, particle1 in enumerate(
                tqdm(particle_list,
                     desc='Particle coupling matrix  ',
                     file=sys.stdout,
                     bar_format='{l_bar}{bar}| elapsed: {elapsed} '
                     'remaining: {remaining}')):
            idx1 = np.array(self.index_block(s1))[:, None]
            for s2, particle2 in enumerate(particle_list):
                idx2 = self.index_block(s2)
                coup_mat[idx1, idx2] = (coup.layer_mediated_coupling_block(
                    vacuum_wavelength, particle1, particle2, layer_system,
                    k_parallel) + coup.direct_coupling_block(
                        vacuum_wavelength, particle1, particle2, layer_system))
        self.linear_operator = scipy.sparse.linalg.aslinearoperator(coup_mat)
コード例 #4
0
def test_w_against_prototype():
    part1 = part.Sphere(position=[100, -100, 200],
                        refractive_index=1.7,
                        radius=100,
                        l_max=2,
                        m_max=2)
    part2 = part.Sphere(position=[-100, 200, 300],
                        refractive_index=1.7,
                        radius=100,
                        l_max=2,
                        m_max=2)
    part3 = part.Sphere(position=[200, 200, -300],
                        refractive_index=1.7,
                        radius=100,
                        l_max=2,
                        m_max=2)

    laysys_waveguide = lay.LayerSystem(thicknesses=[0, 500, 0],
                                       refractive_indices=[1, 2, 1])

    w_wg11 = coup.direct_coupling_block(wl, part1, part1, laysys_waveguide)
    w_wg12 = coup.direct_coupling_block(wl, part1, part2, laysys_waveguide)
    w_wg13 = coup.direct_coupling_block(wl, part1, part3, laysys_waveguide)

    w_wg_0010 = 0.078085976865533 + 0.054600388160436j
    assert abs((w_wg12[0, 0] - w_wg_0010) / w_wg_0010) < 1e-5

    w_wg_0110 = -0.014419231182754 + 0.029269376752105j
    assert abs((w_wg12[1, 0] - w_wg_0110) / w_wg_0110) < 1e-5

    w_wg_0912 = -0.118607476554146 + 0.020532217124574j
    assert abs((w_wg12[9, 2] - w_wg_0912) / w_wg_0912) < 1e-5

    assert np.linalg.norm(w_wg11) == 0  # no direct self interaction
    assert np.linalg.norm(
        w_wg13
    ) == 0  # no direct interaction between particles in different layers
コード例 #5
0
    def dissipated_power(self,
                         particle_list,
                         layer_system,
                         show_progress=True):
        r"""Compute the power that the dipole feeds into the system.

        It is computed according to

        .. math::
            P = P_0 + \frac{\omega}{2} \mathrm{Im} (\mathbf{\mu}^* \cdot \mathbf{E}(\mathbf{r}_D))

        where :math:`P_0` is the power that the dipole would feed into an infinte homogeneous medium with the same
        refractive index as the layer that contains the dipole, :math:`\mathbf{r}_D` is the location of the dipole,
        :math:`\omega` is the angular frequency, :math:`\mathbf{\mu}` is the dipole moment and :math:`\mathbf{E}`
        includes the reflections of the dipole field from the layer interfaces, as well as the scattered field from all
        particles.

        Args:
            particle_list (list of smuthi.particles.Particle objects): scattering particles
            layer_system (smuthi.layers.LayerSystem):                  stratified medium
            show_progress (bool):                                      if true, display progress
            
        Returns:
            dissipated power as float
        """

        k = layer_system.wavenumber(
            layer_system.layer_number(self.position[2]),
            self.vacuum_wavelength)
        virtual_particle = part.Particle(position=self.position,
                                         l_max=1,
                                         m_max=1)
        scattered_field_swe = fldex.SphericalWaveExpansion(
            k=k,
            l_max=1,
            m_max=1,
            kind='regular',
            reference_point=self.position)

        if show_progress:
            iterator = tqdm(
                particle_list,
                desc='Dipole dissipated power   ',
                file=sys.stdout,
                bar_format=
                '{l_bar}{bar}| elapsed: {elapsed} remaining: {remaining}')
        else:
            iterator = particle_list

        for particle in iterator:
            wd = pc.direct_coupling_block(
                vacuum_wavelength=self.vacuum_wavelength,
                receiving_particle=virtual_particle,
                emitting_particle=particle,
                layer_system=layer_system)

            wr = pc.layer_mediated_coupling_block(
                vacuum_wavelength=self.vacuum_wavelength,
                receiving_particle=virtual_particle,
                emitting_particle=particle,
                layer_system=layer_system,
                k_parallel=self.k_parallel)

            scattered_field_swe.coefficients += np.dot(
                wd + wr, particle.scattered_field.coefficients)

        e_x_scat, e_y_scat, e_z_scat = scattered_field_swe.electric_field(
            x=self.position[0], y=self.position[1], z=self.position[2])

        e_x_in, e_y_in, e_z_in = self.electric_field(
            x=self.position[0],
            y=self.position[1],
            z=self.position[2],
            layer_system=layer_system,
            include_direct_field=False)

        power = self.angular_frequency() / 2 * (
            np.conjugate(self.dipole_moment[0]) *
            (e_x_scat + e_x_in) + np.conjugate(self.dipole_moment[1]) *
            (e_y_scat + e_y_in) + np.conjugate(self.dipole_moment[2]) *
            (e_z_scat + e_z_in)).imag
        return self.dissipated_power_homogeneous_background(
            layer_system) + power
コード例 #6
0
# Test fails for mmax != lmax,
# Computation of matrix elements in the laboratory coordinate system of degree l
# require the knowledge of all orders m of same degree l: m = (-l, -l + 1, ..., l - 1, l)
# see e.g.:     Mishchenko et al., Scattering, Absorption, and Emission of Light by Small Particles,
#               Cambridge University Press, 2002. Eq. (5.29) p. 120

#spheroid1 = part.Spheroid(position=[0, 0, 400],euler_angles=[0, 0, 0],
#                          refractive_index=2.4 + 0.0j, semi_axis_c=50, semi_axis_a=100, l_max=2, m_max=1)
#
#spheroid2 = part.Spheroid(position=[0,0,0],euler_angles=[0, 0, 0],
#                          refractive_index=2.4 + 0.0j, semi_axis_c=100, semi_axis_a=50, l_max=2, m_max=2)

# conventional coupling using svwf addition theorem
W = pacou.direct_coupling_block(vacuum_wavelength=wl,
                                receiving_particle=spheroid2,
                                emitting_particle=spheroid1,
                                layer_system=lay_sys)

# plane wave coupling
k_parallel = coord.complex_contour(
    vacuum_wavelength=wl,
    neff_waypoints=[0, 0.9, 0.9 - 0.1j, 1.1 - 0.1j, 1.1, 7],
    neff_resolution=1e-3)
W_pvwf = pacou.direct_coupling_block_pvwf_mediated(
    vacuum_wavelength=wl,
    receiving_particle=spheroid2,
    emitting_particle=spheroid1,
    layer_system=lay_sys,
    k_parallel=k_parallel)

コード例 #7
0
                      refractive_index=1.7 + 0.0j,
                      radius=90,
                      l_max=3,
                      m_max=3)
particle_list = [sphere1, sphere2, sphere3]

# initialize layer system object
lay_sys = lay.LayerSystem([0, 400, 0], [1.5, 2 + 0.01j, 1])

phi12 = np.arctan2(sphere1.position[1] - sphere2.position[1],
                   sphere1.position[0] - sphere2.position[0])
rho12 = np.sqrt(
    sum([(sphere1.position[i] - sphere2.position[i])**2 for i in range(3)]))
wr12 = coup.layer_mediated_coupling_block(vacuum_wavelength, sphere1, sphere2,
                                          lay_sys)
w12 = coup.direct_coupling_block(vacuum_wavelength, sphere1, sphere2, lay_sys)

phi13 = np.arctan2(sphere1.position[1] - sphere3.position[1],
                   sphere1.position[0] - sphere3.position[0])
rho13 = np.sqrt(
    sum([(sphere1.position[i] - sphere3.position[i])**2 for i in range(3)]))
wr13 = coup.layer_mediated_coupling_block(vacuum_wavelength, sphere1, sphere3,
                                          lay_sys)
w13 = coup.direct_coupling_block(vacuum_wavelength, sphere1, sphere3, lay_sys)

# initialize initial field object
init_fld = init.GaussianBeam(vacuum_wavelength=vacuum_wavelength,
                             polar_angle=beam_polar_angle,
                             azimuthal_angle=beam_azimuthal_angle,
                             polarization=beam_polarization,
                             amplitude=beam_amplitude,