def simsmuthi(ii, lams, nkdata, fname, rad, subri): wl = lams[ii] parri = nkdata[ii] angles = np.linspace(0, np.pi, 181) z0 = -rad pos = LoadPosFile(fname, cc, rad, z0) par_list = PrepareIdenticalParticles(positions=pos, ref_ind=parri, radius=rad) coord.set_default_k_parallel(wl, neff_resolution=5e-3, neff_max=subri + 1) two_layers = smuthi.layers.LayerSystem(thicknesses=[0, 0], refractive_indices=[1, subri]) plane_wave = smuthi.initial_field.PlaneWave( vacuum_wavelength=wl, polar_angle=0, # from top azimuthal_angle=0, polarization=0) # 0=TE 1=TM if len(par_list) == 1: simulation = smuthi.simulation.Simulation(layer_system=two_layers, particle_list=par_list, initial_field=plane_wave, solver_type='gmres') else: simulation = smuthi.simulation.Simulation( layer_system=two_layers, particle_list=par_list, initial_field=plane_wave, solver_type='KCSolver', store_coupling_matrix=False, coupling_matrix_lookup_resolution=3) simulation.run() # evaluate differential scattering cross section dscs = smuthi.scattered_field.scattering_cross_section( initial_field=plane_wave, particle_list=par_list, layer_system=two_layers, polar_angles=angles) cext0 = smuthi.scattered_field.extinction_cross_section( plane_wave, par_list, two_layers) scat = dscs.integral() cext = cext0['top'] + cext0['bottom'] return cext, scat
def simsmuthi(wl, parri, par_list, subri=1, topri=1, neff_res=5e-3): """ Default smuthi simulation for particles on a substrate Specular plane wave incidence with user-specified wavelength. Important note: all particles must be made of the same material! :param wl: wavelength :param parri: refractive index data of the particle :param subri: substrate refractive index (default: 1) :param topri: refractive index in which the particle is embedded (default: 1) :return: tuple with extinction and scattering cross-sections """ for jj in range(len(par_list)): par_list[jj].refractive_index = parri coord.set_default_k_parallel(wl, neff_resolution=neff_res, neff_max=subri + 1, neff_imag=1e-2) two_layers = smuthi.layers.LayerSystem(thicknesses=[0, 0], refractive_indices=[topri, subri]) plane_wave = smuthi.initial_field.PlaneWave( vacuum_wavelength=wl, polar_angle=0, # from top azimuthal_angle=0, polarization=0) # 0=TE 1=TM if len(par_list) < 3: simulation = smuthi.simulation.Simulation(layer_system=two_layers, particle_list=par_list, initial_field=plane_wave, solver_type='gmres') else: simulation = smuthi.simulation.Simulation( layer_system=two_layers, particle_list=par_list, initial_field=plane_wave, solver_type='KCSolver', store_coupling_matrix=False, coupling_matrix_lookup_resolution=3) simulation.run() return simulation
refractive_index=1.52, radius=100, l_max=3) # list of all scattering particles (only one in this case) one_sphere = [sphere] # Initial field plane_wave = smuthi.initial_field.PlaneWave( vacuum_wavelength=550, polar_angle=-np.pi, # from top azimuthal_angle=0, polarization=0) # 0=TE 1=TM # Initialize and run simulation simulation = smuthi.simulation.Simulation(layer_system=two_layers, particle_list=one_sphere, initial_field=plane_wave) simulation.run() # Show differential scattering cross section dscs = smuthi.scattered_field.scattering_cross_section( initial_field=plane_wave, particle_list=one_sphere, layer_system=two_layers) smuthi.graphical_output.show_far_field(dscs, save_plots=True, show_plots=False, outputdir='sphere_on_substrate')
def GetTSCS(WL, core_r, index_NP, samples): # Initialize a plane wave object the initial field plane_wave = smuthi.initial_field.PlaneWave( vacuum_wavelength=WL, polar_angle=-np.pi, # normal incidence, from top azimuthal_angle=0, polarization=1) # 0 stands for TE, 1 stands for TM # Initialize the layer system object # The coordinate system is such that the interface between the first two layers defines the plane z=0. two_layers = smuthi.layers.LayerSystem( thicknesses=[0, 0], # substrate, ambient refractive_indices=[1.0, 1.0]) # like aluminum, SiO2, air # Define the scattering particles particle_grid = [] spacer = 1.1 * core_r #nm sphere = smuthi.particles.Sphere( position=[0, 0, 40], #core_r+spacer], refractive_index=index_NP, radius=core_r, l_max=3) # choose l_max with regard to particle size and material # higher means more accurate but slower particle_grid.append(sphere) # Define contour for Sommerfeld integral smuthi.coordinates.set_default_k_parallel( vacuum_wavelength=plane_wave.vacuum_wavelength, neff_resolution=5e-3, # smaller value means more accurate but slower neff_max=2) # should be larger than the highest refractive # index of the layer system global total_runs if total_runs == 0: log_to_terminal = True print("\n\n\t\tExample of solver output for the first run:\n\n") total_runs += 1 else: log_to_terminal = False # Initialize and run simulation simulation = smuthi.simulation.Simulation( layer_system=two_layers, particle_list=particle_grid, initial_field=plane_wave, solver_type='LU', # solver_type='gmres', solver_tolerance=1e-5, store_coupling_matrix=True, coupling_matrix_lookup_resolution=None, # store_coupling_matrix=False, # coupling_matrix_lookup_resolution=5, coupling_matrix_interpolator_kind='cubic', log_to_file=False, log_to_terminal=log_to_terminal) simulation.run() p_angles = np.linspace(0, np.pi, samples, dtype=float) a_angles = np.linspace(0, 2.0 * np.pi, samples, dtype=float) #print(angles) scattering_cross_section = smuthi.scattered_field.scattering_cross_section( initial_field=plane_wave, particle_list=particle_grid, layer_system=two_layers, polar_angles=p_angles, azimuthal_angles=a_angles) Q_sca = (scattering_cross_section.top().integral()[0] + scattering_cross_section.top().integral()[1] + scattering_cross_section.bottom().integral()[0] + scattering_cross_section.bottom().integral()[1]).real / ( np.pi * core_r**2) return Q_sca
def GetTopTSCS(WL, index_chrome, index_gold, l_max, neff_max, sample): #smuthi.layers.set_precision(1000) # Initialize the layer system object # The coordinate system is such that the interface between the # first two layers defines the plane z=0. thickness_chrome = sample[1] thickness_gold = sample[2] two_layers = smuthi.layers.LayerSystem( thicknesses=[0, thickness_gold, thickness_chrome, 0], # ambient, substrate refractive_indices=[1.0, index_gold, index_chrome, index_glass]) # like glass, air # Define the scattering particles particle_grid = [] sphere = smuthi.particles.Sphere( position=[0, 0, -spacer / 2.0], refractive_index=index_glass, radius=spacer / 2.0, l_max=l_max) # choose l_max with regard to particle size and material # higher means more accurate but slower particle_grid.append(sphere) sphere = smuthi.particles.Sphere( position=[0, 0, -spacer - core_r * 2 - spacer * 2 - stm_r], refractive_index=index_gold, radius=stm_r, l_max=l_max) # choose l_max with regard to particle size and material # higher means more accurate but slower particle_grid.append(sphere) # Define contour for Sommerfeld integral alpha = np.linspace(0, 2 * np.pi, 100) smuthi.coordinates.set_default_k_parallel( vacuum_wavelength=WL, neff_resolution=1e-2, neff_max=neff_max # ,neff_waypoints=[0,0.9-0.15j, 8.7-0.15j, 8.7, neff_max] ) # smuthi.coordinates.set_default_k_parallel(vacuum_wavelength=WL, # neff_resolution=1e-2, # neff_waypoints=[0,0.9-0.15j, 1.1-0.15j, 1.2, neff_max] ) dipole_source = smuthi.initial_field.DipoleSource( vacuum_wavelength=WL, dipole_moment=dipole_moment, position=[0, 0, -spacer - core_r * 2 - spacer], # position=[0, 0, -spacer], azimuthal_angles=alpha) # Initialize and run simulation simulation = smuthi.simulation.Simulation( layer_system=two_layers, particle_list=particle_grid, initial_field=dipole_source, solver_type='LU', # solver_type='gmres', solver_tolerance=1e-5, store_coupling_matrix=True, coupling_matrix_lookup_resolution=None, # store_coupling_matrix=False, # coupling_matrix_lookup_resolution=5, coupling_matrix_interpolator_kind='cubic', log_to_file=False, log_to_terminal=False) simulation.run() #polar = np.linspace(0, 0.228857671*np.pi, 100) # 0.21*pi rad == 37.8 grad polar = np.linspace(0, 0.21 * np.pi, 100) # 0.21*pi rad == 37.8 grad total_far_field, initial_far_field, scattered_far_field = smuthi.scattered_field.total_far_field( initial_field=dipole_source, particle_list=particle_grid, layer_system=two_layers, polar_angles=polar) diss_pow = dipole_source.dissipated_power(particle_grid, two_layers) assert abs(diss_pow.imag / diss_pow) < 1e-8 diss_pow = diss_pow.real top_pow, bottom_pow = 0, 0 P0 = dipole_source.dissipated_power_homogeneous_background( layer_system=two_layers) top_pow = sum(total_far_field.integral()).real #sum both polarizations return WL, top_pow, diss_pow, P0, diss_pow / P0
if use_gpu and not cu.use_gpu: print("Failed to load pycuda, skipping simulation") sys.exit(1) print("number of particles = " + str(len(smuthi_spheres))) simulation = smuthi.simulation.Simulation( layer_system=two_layers, particle_list=smuthi_spheres, initial_field=smuthi_plane_wave, solver_type='gmres', store_coupling_matrix=False, coupling_matrix_interpolator_kind='linear', coupling_matrix_lookup_resolution=50, #5, solver_tolerance=1e-4, length_unit='nm') prep_time, solution_time, post_time = simulation.run() log_file = open(projects_directory_location + "/log.txt", 'a') log_file.write("Prep, Solution, Post times are: " + str(prep_time) + ", " + str(solution_time) + ", " + str(post_time) + "\n") log_file.close() vacuum_wavelength = simulation.initial_field.vacuum_wavelength dim1vec = np.arange(-1000, 1000 + 25 / 2, 25) dim2vec = np.arange(-1000, 1000 + 25 / 2, 25) xarr, yarr = np.meshgrid(dim1vec, dim2vec) zarr = xarr - xarr - focal_length_nm scat_fld_exp = sf.scattered_field_piecewise_expansion( vacuum_wavelength, simulation.particle_list,
def simulate_N_spheres(number_of_spheres=100, direct_inversion=True, use_gpu=False, solver_tolerance=5e-4, lookup_resolution=5, interpolation_order='linear', make_illustrations=False): # Initialize the layer system: substrate (glass) and ambient (air) two_layers = smuthi.layers.LayerSystem(thicknesses=[0, 0], refractive_indices=[1.52, 1]) # Initial field plane_wave = smuthi.initial_field.PlaneWave( vacuum_wavelength=550, polar_angle=np.pi, # from top azimuthal_angle=0, polarization=0) # 0=TE 1=TM spheres_list = vogel_spiral(number_of_spheres) # Initialize and run simulation cu.enable_gpu(use_gpu) if use_gpu and not cu.use_gpu: print("Failed to load pycuda, skipping simulation") return [0, 0, 0] if direct_inversion: simulation = smuthi.simulation.Simulation(layer_system=two_layers, particle_list=spheres_list, initial_field=plane_wave) else: simulation = smuthi.simulation.Simulation( layer_system=two_layers, particle_list=spheres_list, initial_field=plane_wave, solver_type='gmres', solver_tolerance=solver_tolerance, store_coupling_matrix=False, coupling_matrix_lookup_resolution=lookup_resolution, coupling_matrix_interpolator_kind=interpolation_order) preparation_time, solution_time, _ = simulation.run() # compute cross section ecs = smuthi.postprocessing.far_field.extinction_cross_section( initial_field=plane_wave, particle_list=spheres_list, layer_system=two_layers) if make_illustrations: azimuthal_angles = np.arange(0, 361, 0.5, dtype=float) * np.pi / 180 polar_angles = np.arange(0, 181, 0.25, dtype=float) * np.pi / 180 dscs = smuthi.postprocessing.far_field.scattering_cross_section( initial_field=plane_wave, particle_list=spheres_list, layer_system=two_layers, polar_angles=polar_angles, azimuthal_angles=azimuthal_angles, ) # display differential scattering cross section smuthi.postprocessing.graphical_output.show_far_field( far_field=dscs, save_plots=True, show_plots=True, save_data=False, tag='dscs_%ispheres' % number_of_spheres, log_scale=True) xlim = max([abs(sphere.position[0]) for sphere in spheres_list]) * 1.1 plt.figure() plt.xlim([-xlim, xlim]) plt.xlabel('x (nm)') plt.ylabel('y (nm)') plt.ylim([-xlim, xlim]) plt.gca().set_aspect("equal") plt.title("Vogel spiral with %i spheres" % number_of_spheres) smuthi.postprocessing.graphical_output.plot_particles( -1e5, 1e5, -1e5, 1e5, 0, 0, spheres_list, 1000, False) plt.savefig("vogel_spiral_%i.png" % number_of_spheres) return [(ecs["top"] + ecs["bottom"]).real, preparation_time, solution_time]