Example #1
0
    def propagated_far_field(self, layer_system):
        """Evaluate the far field intensity of the reflected / transmitted initial field.

        Args:
            layer_system (smuthi.layers.LayerSystem):           Stratified medium

        Returns:
            A tuple of smuthi.field_expansion.FarField objects, one for forward (i.e., into the top hemisphere) and one
            for backward propagation (bottom hemisphere).
        """
        i_top = layer_system.number_of_layers() - 1
        top_ff = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=self.vacuum_wavelength,
            plane_wave_expansion=self.plane_wave_expansion(
                layer_system, i_top)[0])
        bottom_ff = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=self.vacuum_wavelength,
            plane_wave_expansion=self.plane_wave_expansion(layer_system, 0)[1])

        return top_ff, bottom_ff
Example #2
0
    def initial_intensity(self, layer_system):
        """Evaluate the incoming intensity of the initial field.

        Args:
            layer_system (smuthi.layers.LayerSystem):           Stratified medium

        Returns:
            A smuthi.field_expansion.FarField object holding the initial intensity information.
        """
        if np.cos(self.polar_angle) > 0:  # bottom illumination
            ff = fldex.pwe_to_ff_conversion(
                vacuum_wavelength=self.vacuum_wavelength,
                plane_wave_expansion=self.plane_wave_expansion(
                    layer_system, 0)[0])
        else:  # top illumination
            i_top = layer_system.number_of_layers() - 1
            ff = fldex.pwe_to_ff_conversion(
                vacuum_wavelength=self.vacuum_wavelength,
                plane_wave_expansion=self.plane_wave_expansion(
                    layer_system, i_top)[1])
        return ff
Example #3
0
def total_far_field(initial_field,
                    particle_list,
                    layer_system,
                    polar_angles='default',
                    azimuthal_angles='default'):
    """
    Evaluate the total far field, the initial far field and the scattered far field. Cannot be used if initial field
    is a plane wave.
    
    Args:
        initial_field (smuthi.initial_field.InitialField): represents the initial field
        particle_list (list):                       list of smuthi.Particle objects
        layer_system (smuthi.layers.LayerSystem):   represents the stratified medium
        polar_angles (numpy.ndarray or str):        polar angles values (radian). 
                                                    if 'default', use smuthi.coordinates.default_polar_angles
        azimuthal_angles (numpy.ndarray or str):    azimuthal angle values (radian)
                                                    if 'default', use smuthi.coordinates.default_azimuthal_angles

    Returns:
        A tuple of three smuthi.field_expansion.FarField objects for total, initial and scattered far field. Mind that the scattered far field
        has no physical meaning and is for illustration purposes only. 
    """
    if not (type(initial_field).__name__ == 'GaussianBeam'
            or type(initial_field).__name__ == 'DipoleSource'
            or type(initial_field).__name__ == 'DipoleCollection'):
        raise ValueError('only for Gaussian beams and dipole sources')
    omega = initial_field.angular_frequency()
    vacuum_wavelength = initial_field.vacuum_wavelength
    if type(polar_angles) == str and polar_angles == 'default':
        polar_angles = coord.default_polar_angles
    if type(azimuthal_angles) == str and azimuthal_angles == 'default':
        azimuthal_angles = coord.default_azimuthal_angles

    if any(polar_angles.imag):
        raise ValueError("complex angles not allowed in far field")

    i_top = layer_system.number_of_layers() - 1
    top_polar_angles = polar_angles[polar_angles < (np.pi / 2)]
    bottom_polar_angles = polar_angles[polar_angles > (np.pi / 2)]
    neff_top = np.sort(
        np.sin(top_polar_angles) * layer_system.refractive_indices[i_top])
    neff_bottom = np.sort(
        np.sin(bottom_polar_angles) * layer_system.refractive_indices[0])

    if len(top_polar_angles
           ) > 1 and layer_system.refractive_indices[i_top].imag == 0:
        pwe_scat_top, _ = scattered_field_pwe(
            vacuum_wavelength,
            particle_list,
            layer_system,
            i_top,
            k_parallel=neff_top * omega,
            azimuthal_angles=azimuthal_angles,
            include_direct=True,
            include_layer_response=True)
        pwe_in_top, _ = initial_field.plane_wave_expansion(
            layer_system,
            i_top,
            k_parallel_array=neff_top * omega,
            azimuthal_angles_array=azimuthal_angles)
        pwe_top = pwe_scat_top + pwe_in_top
        top_far_field = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength, plane_wave_expansion=pwe_top)
        top_far_field_init = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength,
            plane_wave_expansion=pwe_in_top)
        top_far_field_scat = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength,
            plane_wave_expansion=pwe_scat_top)
    else:
        top_far_field = None
        top_far_field_init = None
        top_far_field_scat = None

    if len(bottom_polar_angles
           ) > 1 and layer_system.refractive_indices[0].imag == 0:
        _, pwe_scat_bottom = scattered_field_pwe(
            vacuum_wavelength,
            particle_list,
            layer_system,
            0,
            k_parallel=neff_bottom * omega,
            azimuthal_angles=azimuthal_angles,
            include_direct=True,
            include_layer_response=True)
        _, pwe_in_bottom = initial_field.plane_wave_expansion(
            layer_system,
            0,
            k_parallel_array=neff_bottom * omega,
            azimuthal_angles_array=azimuthal_angles)
        pwe_bottom = pwe_scat_bottom + pwe_in_bottom
        bottom_far_field = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength,
            plane_wave_expansion=pwe_bottom)
        bottom_far_field_init = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength,
            plane_wave_expansion=pwe_in_bottom)
        bottom_far_field_scat = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength,
            plane_wave_expansion=pwe_scat_bottom)
    else:
        bottom_far_field = None
        bottom_far_field_init = None
        bottom_far_field_scat = None

    if top_far_field is not None:
        far_field = top_far_field
        far_field_init = top_far_field_init
        far_field_scat = top_far_field_scat
        if bottom_far_field is not None:
            far_field.append(bottom_far_field)
            far_field_init.append(bottom_far_field_init)
            far_field_scat.append(bottom_far_field_scat)
    else:
        far_field = bottom_far_field
        far_field_init = bottom_far_field_init
        far_field_scat = bottom_far_field_scat

    far_field.polar_angles = far_field.polar_angles.real
    far_field_init.polar_angles = far_field_init.polar_angles.real
    far_field_scat.polar_angles = far_field_scat.polar_angles.real
    return far_field, far_field_init, far_field_scat
Example #4
0
def scattered_far_field(vacuum_wavelength,
                        particle_list,
                        layer_system,
                        polar_angles='default',
                        azimuthal_angles='default'):
    """
    Evaluate the scattered far field.

    Args:
        vacuum_wavelength (float):                  in length units
        particle_list (list):                       list of smuthi.Particle objects
        layer_system (smuthi.layers.LayerSystem):   represents the stratified medium
        polar_angles (numpy.ndarray or str):        polar angles values (radian). 
                                                    if 'default', use smuthi.coordinates.default_polar_angles
        azimuthal_angles (numpy.ndarray or str):    azimuthal angle values (radian)
                                                    if 'default', use smuthi.coordinates.default_azimuthal_angles

    Returns:
        A smuthi.field_expansion.FarField object of the scattered field.
    """
    omega = coord.angular_frequency(vacuum_wavelength)
    if type(polar_angles) == str and polar_angles == 'default':
        polar_angles = coord.default_polar_angles
    if type(azimuthal_angles) == str and azimuthal_angles == 'default':
        azimuthal_angles = coord.default_azimuthal_angles

    if any(polar_angles.imag):
        raise ValueError("complex angles not allowed in far field")

    i_top = layer_system.number_of_layers() - 1
    top_polar_angles = polar_angles[polar_angles < (np.pi / 2)]
    bottom_polar_angles = polar_angles[polar_angles > (np.pi / 2)]
    neff_top = np.sort(
        np.sin(top_polar_angles) * layer_system.refractive_indices[i_top])
    neff_bottom = np.sort(
        np.sin(bottom_polar_angles) * layer_system.refractive_indices[0])

    if len(top_polar_angles
           ) > 1 and layer_system.refractive_indices[i_top].imag == 0:
        pwe_top, _ = scattered_field_pwe(vacuum_wavelength,
                                         particle_list,
                                         layer_system,
                                         i_top,
                                         k_parallel=neff_top * omega,
                                         azimuthal_angles=azimuthal_angles,
                                         include_direct=True,
                                         include_layer_response=True)
        top_far_field = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength, plane_wave_expansion=pwe_top)
    else:
        top_far_field = None

    if len(bottom_polar_angles
           ) > 1 and layer_system.refractive_indices[0].imag == 0:
        _, pwe_bottom = scattered_field_pwe(vacuum_wavelength,
                                            particle_list,
                                            layer_system,
                                            0,
                                            k_parallel=neff_bottom * omega,
                                            azimuthal_angles=azimuthal_angles,
                                            include_direct=True,
                                            include_layer_response=True)
        bottom_far_field = fldex.pwe_to_ff_conversion(
            vacuum_wavelength=vacuum_wavelength,
            plane_wave_expansion=pwe_bottom)
    else:
        bottom_far_field = None

    if top_far_field is not None:
        far_field = top_far_field
        if bottom_far_field is not None:
            far_field.append(bottom_far_field)
    else:
        far_field = bottom_far_field

    far_field.polar_angles = far_field.polar_angles.real
    return far_field