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
Exemple #2
0
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
Exemple #3
0
                                 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,
Exemple #7
0
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]