def test_wr_against_prototype():
    laysys_substrate = lay.LayerSystem(thicknesses=[0, 0],
                                       refractive_indices=[2 + 0.1j, 1])

    wr_sub00 = coup.layer_mediated_coupling_block(wl, part1, part1,
                                                  laysys_substrate)
    wr_sub01 = coup.layer_mediated_coupling_block(wl, part1, part2,
                                                  laysys_substrate)

    wr_sub_0000 = -0.116909038698419 - 0.013001770175717j
    assert abs((wr_sub00[0, 0] - wr_sub_0000) / wr_sub_0000) < 1e-5
    wr_sub_0010 = 0.051728301055665 - 0.030410521218822j
    assert abs((wr_sub01[0, 0] - wr_sub_0010) / wr_sub_0010) < 1e-5
    wr_sub_0110 = -0.028137473050619 - 0.012620163432327j
    assert abs((wr_sub01[1, 0] - wr_sub_0110) / wr_sub_0110) < 1e-5

    laysys_waveguide = lay.LayerSystem(thicknesses=[0, 500, 0],
                                       refractive_indices=[1, 2, 1])
    wr_wg00 = coup.layer_mediated_coupling_block(wl, part1, part1,
                                                 laysys_waveguide)
    wr_wg01 = coup.layer_mediated_coupling_block(wl, part1, part2,
                                                 laysys_waveguide)

    wr_wg_0000 = -0.058321374924359 - 0.030731607595288j
    assert (abs(wr_wg00[0, 0] - wr_wg_0000) / wr_wg_0000) < 1e-5
    wr_wg_0010 = -0.065332285111172 - 0.007633555190358j
    assert (abs(wr_wg01[0, 0] - wr_wg_0010) / wr_wg_0010) < 1e-5
    wr_wg_0110 = 0.002514697648047 - 0.001765938544514j
    assert (abs(wr_wg01[1, 0] - wr_wg_0110) / wr_wg_0110) < 1e-5
Пример #2
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
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)
Пример #4
0
    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)
Пример #5
0
def layercoupling(wl, par_list, layers, M):
    k0 = 2 * np.pi / wl
    c = -6 * 1j * k0**(-3) / 4
    N_particles = len(par_list)
    blocksize = 6
    Wr = np.zeros((N_particles * blocksize, N_particles * blocksize),
                  dtype=complex)
    for ii in range(N_particles):
        for jj in range(N_particles):
            Wr[ii * blocksize:blocksize * (ii + 1), jj * blocksize:blocksize *
               (jj + 1)] = coup.layer_mediated_coupling_block(
                   wl, par_list[ii], par_list[jj], layers, 'default')
    Gr = change_basis(Wr, M, c)
    return Gr
Пример #6
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
Пример #7
0
                      m_max=2)
sphere3 = part.Sphere(position=[202, 100, 150],
                      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,