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