def test_swe2pwe():
    ex, ey, ez = swe.electric_field(x, y, z)
    pwe_up, pwe_down = fldex.swe_to_pwe_conversion(swe, k_parallel=kp, azimuthal_angles=a, layer_system=layer_system)
    ex2, ey2, ez2 = pwe_up.electric_field(x, y, z)
    err2 = abs(ex - ex2) ** 2 + abs(ey - ey2) ** 2 + abs(ez - ez2) ** 2
    norme2 = abs(ex) ** 2 + abs(ey) ** 2 + abs(ez) ** 2
    print('relative error:', np.sqrt(err2 / norme2))
    assert np.sqrt(err2 / norme2) < 5e-3
예제 #2
0
    def piecewise_field_expansion(self,
                                  layer_system,
                                  include_direct_field=True,
                                  include_layer_response=True):
        """Compute a piecewise field expansion of the dipole field.

        Args:
            layer_system (smuthi.layer.LayerSystem):    stratified medium
            include_direct_field (bool):                if True (default), the direct dipole field is included.
                                                        otherwise, only the layer response of the dipole field is
                                                        returned.
            include_layer_response (bool):              if True (default), the layer response of the dipole field is 
                                                        included. otherwise, only the direct dipole field is
                                                        returned.
                                        

        Returns:
            smuthi.field_expansion.PiecewiseWaveExpansion object
        """
        pfe = fldex.PiecewiseFieldExpansion()
        if include_direct_field:
            pfe.expansion_list.append(
                self.outgoing_spherical_wave_expansion(layer_system))
        if include_layer_response:
            for i in range(layer_system.number_of_layers()):
                # layer response as plane wave expansions
                pwe_up, pwe_down = fldex.swe_to_pwe_conversion(
                    swe=self.outgoing_spherical_wave_expansion(layer_system),
                    k_parallel=self.k_parallel,
                    azimuthal_angles=self.azimuthal_angles,
                    layer_system=layer_system,
                    layer_number=i,
                    layer_system_mediated=True)
                if i > 0:
                    pfe.expansion_list.append(pwe_up)
                if i < layer_system.number_of_layers() - 1:
                    pfe.expansion_list.append(pwe_down)

        return pfe
예제 #3
0
def scattered_field_pwe(vacuum_wavelength,
                        particle_list,
                        layer_system,
                        layer_number,
                        k_parallel='default',
                        azimuthal_angles='default',
                        include_direct=True,
                        include_layer_response=True):
    """Calculate the plane wave expansion of the scattered field of a set of particles.

    Args:
        vacuum_wavelength (float):          Vacuum wavelength (length unit)
        particle_list (list):               List of Particle objects
        layer_system (smuthi.layers.LayerSystem):  Stratified medium
        layer_number (int):                 Layer number in which the plane wave expansion should be valid
        k_parallel (numpy.ndarray or str):          in-plane wavenumbers array. 
                                                    if 'default', use smuthi.coordinates.default_k_parallel
        azimuthal_angles (numpy.ndarray or str):    azimuthal angles array
                                                    if 'default', use smuthi.coordinates.default_azimuthal_angles
        include_direct (bool):              If True, include the direct scattered field
        include_layer_response (bool):      If True, include the layer system response

    Returns:
        A tuple of PlaneWaveExpansion objects for upgoing and downgoing waves.
    """

    sys.stdout.write(
        'Evaluating scattered field plane wave expansion in layer number %i ...\n'
        % layer_number)
    sys.stdout.flush()

    omega = coord.angular_frequency(vacuum_wavelength)
    k = omega * layer_system.refractive_indices[layer_number]
    z = layer_system.reference_z(layer_number)
    vb = (layer_system.lower_zlimit(layer_number),
          layer_system.upper_zlimit(layer_number))
    pwe_up = fldex.PlaneWaveExpansion(k=k,
                                      k_parallel=k_parallel,
                                      azimuthal_angles=azimuthal_angles,
                                      kind='upgoing',
                                      reference_point=[0, 0, z],
                                      lower_z=vb[0],
                                      upper_z=vb[1])
    pwe_down = fldex.PlaneWaveExpansion(k=k,
                                        k_parallel=k_parallel,
                                        azimuthal_angles=azimuthal_angles,
                                        kind='downgoing',
                                        reference_point=[0, 0, z],
                                        lower_z=vb[0],
                                        upper_z=vb[1])

    for iS, particle in enumerate(
            tqdm(particle_list,
                 desc='Scatt. field pwe          ',
                 file=sys.stdout,
                 bar_format='{l_bar}{bar}| elapsed: {elapsed} '
                 'remaining: {remaining}')):

        i_iS = layer_system.layer_number(particle.position[2])

        # direct contribution
        if i_iS == layer_number and include_direct:
            pu, pd = fldex.swe_to_pwe_conversion(
                swe=particle.scattered_field,
                k_parallel=k_parallel,
                azimuthal_angles=azimuthal_angles,
                layer_system=layer_system)
            pwe_up = pwe_up + pu
            pwe_down = pwe_down + pd

        # layer mediated contribution
        if include_layer_response:
            pu, pd = fldex.swe_to_pwe_conversion(
                swe=particle.scattered_field,
                k_parallel=k_parallel,
                azimuthal_angles=azimuthal_angles,
                layer_system=layer_system,
                layer_number=layer_number,
                layer_system_mediated=True)
            pwe_up = pwe_up + pu
            pwe_down = pwe_down + pd

    return pwe_up, pwe_down
예제 #4
0
def scattered_field_piecewise_expansion(vacuum_wavelength,
                                        particle_list,
                                        layer_system,
                                        k_parallel='default',
                                        azimuthal_angles='default',
                                        layer_numbers=None):
    """Compute a piecewise field expansion of the scattered field.

    Args:
        vacuum_wavelength (float):                  vacuum wavelength
        particle_list (list):                       list of smuthi.particles.Particle objects
        layer_system (smuthi.layers.LayerSystem):   stratified medium
        k_parallel (numpy.ndarray or str):          in-plane wavenumbers array. 
                                                    if 'default', use smuthi.coordinates.default_k_parallel
        azimuthal_angles (numpy.ndarray or str):    azimuthal angles array
                                                    if 'default', use smuthi.coordinates.default_azimuthal_angles
        layer_numbers (list):                       if specified, append only plane wave expansions for these layers
        

    Returns:
        scattered field as smuthi.field_expansion.PiecewiseFieldExpansion object

    """

    if layer_numbers is None:
        layer_numbers = range(layer_system.number_of_layers())

    sfld = fldex.PiecewiseFieldExpansion()
    for i in tqdm(layer_numbers,
                  desc='Scatt. field expansion    ',
                  file=sys.stdout,
                  bar_format='{l_bar}{bar}| elapsed: {elapsed} '
                  'remaining: {remaining}'):
        # layer mediated scattered field ---------------------------------------------------------------------------
        k = coord.angular_frequency(
            vacuum_wavelength) * layer_system.refractive_indices[i]
        ref = [0, 0, layer_system.reference_z(i)]
        vb = (layer_system.lower_zlimit(i), layer_system.upper_zlimit(i))
        pwe_up = fldex.PlaneWaveExpansion(k=k,
                                          k_parallel=k_parallel,
                                          azimuthal_angles=azimuthal_angles,
                                          kind='upgoing',
                                          reference_point=ref,
                                          lower_z=vb[0],
                                          upper_z=vb[1])
        pwe_down = fldex.PlaneWaveExpansion(k=k,
                                            k_parallel=k_parallel,
                                            azimuthal_angles=azimuthal_angles,
                                            kind='downgoing',
                                            reference_point=ref,
                                            lower_z=vb[0],
                                            upper_z=vb[1])
        for particle in particle_list:
            add_up, add_down = fldex.swe_to_pwe_conversion(
                particle.scattered_field, k_parallel, azimuthal_angles,
                layer_system, i, True)
            pwe_up = pwe_up + add_up
            pwe_down = pwe_down + add_down

        # in bottom_layer, suppress upgoing waves, and in top layer, suppress downgoing waves
        if i > 0:
            sfld.expansion_list.append(pwe_up)
        if i < layer_system.number_of_layers() - 1:
            sfld.expansion_list.append(pwe_down)

    # direct field ---------------------------------------------------------------------------------------------
    for particle in particle_list:
        sfld.expansion_list.append(particle.scattered_field)

    return sfld