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
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
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
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