def test_w_against_wr(): coord.set_default_k_parallel(wl, [0, 0.8, 0.8 - 0.1j, 2.1 - 0.1j, 2.1, 7], 2e-3) laysys_air_1 = lay.LayerSystem(thicknesses=[0, 0], refractive_indices=[1, 1]) laysys_air_2 = lay.LayerSystem(thicknesses=[0, 250, 0], refractive_indices=[1, 1, 1]) part1 = part.Sphere(position=[100, -100, 200], refractive_index=1.7, radius=100, l_max=2, m_max=2) part2 = part.Sphere(position=[-100, 200, 400], refractive_index=1.7, radius=100, l_max=2, m_max=2) w_air_1 = coup.direct_coupling_block(wl, part1, part2, laysys_air_1) wr_air_2 = coup.layer_mediated_coupling_block(wl, part1, part2, laysys_air_2) error = wr_air_2 - w_air_1 np.testing.assert_almost_equal(wr_air_2, w_air_1, decimal=4)
def test_wr_against_prototype(): laysys_substrate = lay.LayerSystem(thicknesses=[0, 0], refractive_indices=[2 + 0.1j, 1]) wr_sub00 = coup.layer_mediated_coupling_block(wl, part1, part1, laysys_substrate) wr_sub01 = coup.layer_mediated_coupling_block(wl, part1, part2, laysys_substrate) wr_sub_0000 = -0.116909038698419 - 0.013001770175717j assert abs((wr_sub00[0, 0] - wr_sub_0000) / wr_sub_0000) < 1e-5 wr_sub_0010 = 0.051728301055665 - 0.030410521218822j assert abs((wr_sub01[0, 0] - wr_sub_0010) / wr_sub_0010) < 1e-5 wr_sub_0110 = -0.028137473050619 - 0.012620163432327j assert abs((wr_sub01[1, 0] - wr_sub_0110) / wr_sub_0110) < 1e-5 laysys_waveguide = lay.LayerSystem(thicknesses=[0, 500, 0], refractive_indices=[1, 2, 1]) wr_wg00 = coup.layer_mediated_coupling_block(wl, part1, part1, laysys_waveguide) wr_wg01 = coup.layer_mediated_coupling_block(wl, part1, part2, laysys_waveguide) wr_wg_0000 = -0.058321374924359 - 0.030731607595288j assert (abs(wr_wg00[0, 0] - wr_wg_0000) / wr_wg_0000) < 1e-5 wr_wg_0010 = -0.065332285111172 - 0.007633555190358j assert (abs(wr_wg01[0, 0] - wr_wg_0010) / wr_wg_0010) < 1e-5 wr_wg_0110 = 0.002514697648047 - 0.001765938544514j assert (abs(wr_wg01[1, 0] - wr_wg_0110) / wr_wg_0110) < 1e-5
def test_layerresponse_method(): fromlayer = 2 tolayer = 1 kp = np.linspace(0, 2) * omega a = np.linspace(0, 2 * np.pi) layer_system = lay.LayerSystem(thicknesses=layer_d, refractive_indices=layer_n) ref = [0, 0, layer_system.reference_z(fromlayer)] pwe_up = fldex.PlaneWaveExpansion(k=omega * 1.2, k_parallel=kp, azimuthal_angles=a, kind='upgoing', reference_point=ref) pwe_up.coefficients[0, :, :] = np.exp(-pwe_up.k_parallel_grid() / omega) pwe_down = fldex.PlaneWaveExpansion(k=omega * 1.2, k_parallel=kp, azimuthal_angles=a, kind='downgoing', reference_point=ref) pwe_down.coefficients[0, :, :] = 2j * np.exp( -pwe_up.k_parallel_grid() / omega * 3) pwe_r_up, pwe_r_down = layer_system.response(pwe_up, fromlayer, tolayer) pwe_r_up2, pwe_r_down2 = layer_system.response(pwe_down, fromlayer, tolayer) pwe_r_up3, pwe_r_down3 = layer_system.response((pwe_up, pwe_down), fromlayer, tolayer)
def test_w_against_wr(): flds.default_Sommerfeld_k_parallel_array = flds.reasonable_Sommerfeld_kpar_contour( vacuum_wavelength=wl, neff_waypoints=[0, 0.8, 0.8 - 0.1j, 2.1 - 0.1j, 2.1, 7], neff_resolution=2e-3) laysys_air_1 = lay.LayerSystem(thicknesses=[0, 0], refractive_indices=[1, 1]) laysys_air_2 = lay.LayerSystem(thicknesses=[0, 250, 0], refractive_indices=[1, 1, 1]) part1 = part.Sphere(position=[100, -100, 200], refractive_index=1.7, radius=100, l_max=2, m_max=2) part2 = part.Sphere(position=[-100, 200, 400], refractive_index=1.7, radius=100, l_max=2, m_max=2) w_air_1 = direct_coupling_block(wl, part1, part2, laysys_air_1) wr_air_2 = layer_mediated_coupling_block(wl, part1, part2, laysys_air_2) error = wr_air_2 - w_air_1 np.testing.assert_almost_equal(wr_air_2, w_air_1, decimal=4)
def testGMRES(self): # Parameter input ---------------------------- vacuum_wavelength = 550 beam_polar_angle = np.pi * 7 / 8 beam_azimuthal_angle = np.pi * 1 / 3 beam_polarization = 0 beam_amplitude = 1 beam_neff_array = np.linspace(0, 2, 501, endpoint=False) beam_waist = 1000 beam_focal_point = [200, 200, 200] #neff_waypoints = [0, 0.5, 0.8 - 0.01j, 2 - 0.01j, 2.5, 5] #neff_discr = 1e-2 # -------------------------------------------- #coord.set_default_k_parallel(vacuum_wavelength, neff_waypoints, neff_discr) # initialize particle object sphere1 = part.Sphere(position=[100, 100, 150], refractive_index=2.4 + 0.0j, radius=110, l_max=4, m_max=4) sphere2 = part.Sphere(position=[-100, -100, 250], refractive_index=1.9 + 0.0j, radius=120, l_max=3, m_max=3) sphere3 = part.Sphere(position=[-200, 100, 300], refractive_index=1.7 + 0.0j, radius=90, l_max=3, m_max=3) particle_list = [sphere1, sphere2, sphere3] # initialize layer system object lay_sys = lay.LayerSystem([0, 400, 0], [2, 1.4, 2]) # initialize initial field object init_fld = init.GaussianBeam(vacuum_wavelength=vacuum_wavelength, polar_angle=beam_polar_angle, azimuthal_angle=beam_azimuthal_angle, polarization=beam_polarization, amplitude=beam_amplitude, reference_point=beam_focal_point, beam_waist=beam_waist, k_parallel_array=beam_neff_array * flds.angular_frequency(vacuum_wavelength)) # initialize simulation object simulation_lu = simul.Simulation(layer_system=lay_sys, particle_list=particle_list, initial_field=init_fld, solver_type='LU', log_to_terminal='nose2' not in sys.modules.keys()) # suppress output if called by nose simulation_lu.run() coefficients_lu = particle_list[0].scattered_field.coefficients simulation_gmres = simul.Simulation(layer_system=lay_sys, particle_list=particle_list, initial_field=init_fld, solver_type='gmres', solver_tolerance=1e-5, log_to_terminal=( not sys.argv[0].endswith('nose2'))) # suppress output if called by nose simulation_gmres.run() coefficients_gmres = particle_list[0].scattered_field.coefficients np.testing.assert_allclose(np.linalg.norm(coefficients_lu), np.linalg.norm(coefficients_gmres), rtol=1e-5)
def test_w_against_prototype(): part1 = part.Sphere(position=[100, -100, 200], refractive_index=1.7, radius=100, l_max=2, m_max=2) part2 = part.Sphere(position=[-100, 200, 300], refractive_index=1.7, radius=100, l_max=2, m_max=2) part3 = part.Sphere(position=[200, 200, -300], refractive_index=1.7, radius=100, l_max=2, m_max=2) laysys_waveguide = lay.LayerSystem(thicknesses=[0, 500, 0], refractive_indices=[1, 2, 1]) w_wg11 = direct_coupling_block(wl, part1, part1, laysys_waveguide) w_wg12 = direct_coupling_block(wl, part1, part2, laysys_waveguide) w_wg13 = direct_coupling_block(wl, part1, part3, laysys_waveguide) w_wg_0010 = 0.078085976865533 + 0.054600388160436j assert abs((w_wg12[0, 0] - w_wg_0010) / w_wg_0010) < 1e-5 w_wg_0110 = -0.014419231182754 + 0.029269376752105j assert abs((w_wg12[1, 0] - w_wg_0110) / w_wg_0110) < 1e-5 w_wg_0912 = -0.118607476554146 + 0.020532217124574j assert abs((w_wg12[9, 2] - w_wg_0912) / w_wg_0912) < 1e-5 assert np.linalg.norm(w_wg11) == 0 # no direct self interaction assert np.linalg.norm(w_wg13) == 0 # no direct interaction between particles in different layers
neff_discr = 1e-3 # -------------------------------------------- flds.default_Sommerfeld_k_parallel_array = flds.reasonable_Sommerfeld_kpar_contour( vacuum_wavelength=vacuum_wavelength, neff_waypoints=neff_waypoints, neff_resolution=neff_discr) # initialize particle object part1 = part.Sphere(position=[100,100,150], refractive_index=2.4+0.0j, radius=120, l_max=lmax) part2 = part.Sphere(position=[-100,-100,250], refractive_index=1.9+0.1j, radius=120, l_max=lmax) # initialize layer system object lay_sys1 = lay.LayerSystem([0, 400, 0], [1.5, 1.7, 1]) lay_sys2 = lay.LayerSystem([0, 200, 200, 0], [1.5, 1.7, 1.7, 1]) # initialize initial field object plane_wave = init.PlaneWave(vacuum_wavelength=vacuum_wavelength, polar_angle=plane_wave_polar_angle, azimuthal_angle=plane_wave_azimuthal_angle, polarization=plane_wave_polarization, amplitude=plane_wave_amplitude, reference_point=[0, 0, 400]) # initialize simulation object simulation1 = simul.Simulation(layer_system=lay_sys1, particle_list=[part1,part2], initial_field=plane_wave, log_to_terminal=(not sys.argv[0].endswith('nose2'))) # suppress output if called by nose simulation1.run() simulation2 = simul.Simulation(layer_system=lay_sys2, particle_list=[part1,part2], initial_field=plane_wave, log_to_terminal=(not sys.argv[0].endswith('nose2'))) # suppress output if called by nose simulation2.run()
21) # another example declaration of wavelengths subri = 2 # substrate refractive index # nkdata = ms.LoadNkData(wl, fname) # use if you want to import Si data from Schinke nkdata = 0 * wl + 4 # particle refractive index CC = 7000 pos = np.array([[0, 0, -rad], [CC * rad, CC * rad, -rad]]) # list of particle positions # pos = ms.LoadPosFile(posname, CC, rad, -rad) # loads position from posname and scales it to match rad N_particles = pos.shape[0] cext_tot = [] for ii in range(len(wl)): # set_default_k_parallel is extremely tricky function from Amos. Use with care. coord.set_default_k_parallel(wl[ii], neff_resolution=5e-3, neff_max=subri + 1) two_layers = layers.LayerSystem(thicknesses=[0, 0], refractive_indices=[1, subri]) par_list = ms.PrepareIdenticalParticles(positions=pos, radius=rad, l_max=1, ref_ind=nkdata[ii]) k0 = 2 * np.pi / wl[ii] c = -6 * 1j * k0**(-3) / 4 M = conversionmatrix(N_particles, c) # not too smart! Sr = layercoupling(wl[ii], par_list, two_layers, M) S = particlecoupling(wl[ii], pos) alfinv = inversepolarizabilities(par_list, wl[ii]) Einc = initial_field(wl[ii], par_list, two_layers) p = solve(alfinv, S, Sr, Einc) cext = extinction_cross_section(wl[ii], Einc, p) cext_tot.append(cext) #print(Einc)
prolate = part.Spheroid(position=[-300, 300, 250], refractive_index=3, semi_axis_a=80, semi_axis_c=150, l_max=lmax) oblate = part.Spheroid(position=[-300, -300, 250], refractive_index=3, semi_axis_a=150, semi_axis_c=80, l_max=lmax) four_particles = [sphere, cylinder, prolate, oblate] # layer system three_layers = lay.LayerSystem(thicknesses=[0, 500, 0], refractive_indices=[1 + 6j, 2, 1.5]) # dipole source dipole = init.DipoleSource(vacuum_wavelength=vacuum_wavelength, dipole_moment=[1, 0, 0], position=[0, 0, 250]) # run simulation simulation = simul.Simulation(layer_system=three_layers, particle_list=four_particles, initial_field=dipole) simulation.run() # near field scat_fld_exp = sf.scattered_field_piecewise_expansion(vacuum_wavelength, four_particles,
k = omega * refractive_index kp_vec1 = np.linspace(0, 0.99, 500) * k kp_vec2 = 1j * np.linspace(0, -0.01, 100) * k + 0.99 * k kp_vec3 = np.linspace(0, 0.02, 200) * k + (0.99 - 0.01j) * k kp_vec4 = 1j * np.linspace(0, 0.01, 100) * k + (1.01 - 0.01j) * k kp_vec5 = np.linspace(0, 6, 1000) * k + 1.01 * k kp = np.concatenate([kp_vec1, kp_vec2, kp_vec3, kp_vec4, kp_vec5]) a = np.linspace(0, 2 * np.pi, num=200) pwe_ref = [-100, -100, -100] swe_ref = [-400, 200, 500] fieldpoint = [-500, 310, 620] vb = [0, 800] layer_system = lay.LayerSystem([0, 0], [1, 1]) x = np.array([fieldpoint[0]]) y = np.array([fieldpoint[1]]) z = np.array([fieldpoint[2]]) swe = fldex.SphericalWaveExpansion(k=k, l_max=3, m_max=3, kind='outgoing', reference_point=swe_ref) swe.coefficients[0] = 2 swe.coefficients[1] = -3j swe.coefficients[16] = 1 swe.coefficients[18] = 0.5
semi_axis_a=50, l_max=8, m_max=8) spheroid2 = part.Spheroid(position=[0, 0, 200], polar_angle=polar_angle, azimuthal_angle=azimuthal_angle, refractive_index=2.4, semi_axis_c=100, semi_axis_a=50, l_max=8, m_max=8) part_list = [spheroid1] part_list2 = [spheroid2] # initialize layer system object lay_sys = lay.LayerSystem([0, 800, 0], [1, 1, 1]) # initialize plane wave objects planewave = init.PlaneWave(vacuum_wavelength=ld, polar_angle=0, azimuthal_angle=0, polarization=0, amplitude=1, reference_point=rD) planewave2 = init.PlaneWave(vacuum_wavelength=ld, polar_angle=polar_angle, azimuthal_angle=azimuthal_angle, polarization=0, amplitude=1, reference_point=rD2)
neff_waypoints=waypoints, neff_resolution=neff_discr) # initialize particle object # first two spheres in top layer sphere1 = part.Sphere(position=[200, 200, 500], refractive_index=2.4 + 0.0j, radius=110, l_max=3, m_max=3) sphere2 = part.Sphere(position=[200, -200, 500], refractive_index=2.4 + 0.0j, radius=110, l_max=3, m_max=3) # third sphere is in same layer as third dipole sphere3 = part.Sphere(position=[-200, -200, -400], refractive_index=2.5 + 0.0j, radius=90, l_max=3, m_max=3) part_list = [sphere1, sphere2, sphere3] # initialize layer system object lay_sys = lay.LayerSystem([0, 400, 0], [1, 2, 1.5]) # initialize dipole object dipole1 = init.DipoleSource(vacuum_wavelength=ld, dipole_moment=D1, position=rD1, k_parallel_array=kpar) dipole2 = init.DipoleSource(vacuum_wavelength=ld, dipole_moment=D2, position=rD2, k_parallel_array=kpar) dipole_collection = init.DipoleCollection(vacuum_wavelength=ld, k_parallel_array=kpar) dipole_collection.append(dipole1) dipole_collection.append(dipole2) dipole_collection_pwe = init.DipoleCollection(vacuum_wavelength=ld, k_parallel_array=kpar, compute_swe_by_pwe=True) dipole_collection_pwe.append(dipole1) dipole_collection_pwe.append(dipole2) def test_swe_methods_agree(): swe1 = dipole_collection.spherical_wave_expansion(sphere1, lay_sys)
def testElectricField(self): try: import pycuda.autoinit except ImportError: self.skipTest('PyCUDA is not available') ld = 550 rD = [100, -100, 100] D = [1e7, 2e7, 3e7] #waypoints = [0, 0.8, 0.8 - 0.1j, 2.1 - 0.1j, 2.1, 4] #neff_discr = 2e-2 #coord.set_default_k_parallel(vacuum_wavelength=ld, neff_waypoints=waypoints, neff_resolution=neff_discr) # initialize particle object sphere1 = part.Sphere(position=[200, 200, 300], refractive_index=2.4 + 0.0j, radius=110, l_max=3, m_max=3) sphere2 = part.Sphere(position=[-200, -200, 300], refractive_index=2.4 + 0.0j, radius=120, l_max=3, m_max=3) sphere3 = part.Sphere(position=[-200, 200, 300], refractive_index=2.5 + 0.0j, radius=90, l_max=3, m_max=3) part_list = [sphere1, sphere2, sphere3] # initialize layer system object lay_sys = lay.LayerSystem([0, 400, 0], [1 + 6j, 2.3, 1.5]) # initialize dipole object dipole = init.DipoleSource(vacuum_wavelength=ld, dipole_moment=D, position=rD) # run simulation simulation = simul.Simulation( layer_system=lay_sys, particle_list=part_list, initial_field=dipole, log_to_terminal='nose2' not in sys.modules.keys()) # suppress output if called by nose simulation.run() xarr = np.array([-300, 400, -100, 200]) yarr = np.array([200, -100, 400, 300]) zarr = np.array([-50, 200, 600, 700]) scat_fld_exp = sf.scattered_field_piecewise_expansion( ld, part_list, lay_sys) e_x_scat_cpu, e_y_scat_cpu, e_z_scat_cpu = scat_fld_exp.electric_field( xarr, yarr, zarr) e_x_init_cpu, e_y_init_cpu, e_z_init_cpu = simulation.initial_field.electric_field( xarr, yarr, zarr, lay_sys) cu.enable_gpu() scat_fld_exp = sf.scattered_field_piecewise_expansion( ld, part_list, lay_sys) e_x_scat_gpu, e_y_scat_gpu, e_z_scat_gpu = scat_fld_exp.electric_field( xarr, yarr, zarr) e_x_init_gpu, e_y_init_gpu, e_z_init_gpu = simulation.initial_field.electric_field( xarr, yarr, zarr, lay_sys) np.testing.assert_allclose(np.linalg.norm(e_x_scat_cpu), np.linalg.norm(e_x_scat_gpu), rtol=1e-5) np.testing.assert_allclose(np.linalg.norm(e_y_scat_cpu), np.linalg.norm(e_y_scat_gpu), rtol=1e-5) np.testing.assert_allclose(np.linalg.norm(e_z_scat_cpu), np.linalg.norm(e_z_scat_gpu), rtol=1e-5) np.testing.assert_allclose(np.linalg.norm(e_x_init_cpu), np.linalg.norm(e_x_init_gpu), rtol=1e-5) np.testing.assert_allclose(np.linalg.norm(e_y_init_cpu), np.linalg.norm(e_y_init_gpu), rtol=1e-5) np.testing.assert_allclose(np.linalg.norm(e_z_init_cpu), np.linalg.norm(e_z_init_gpu), rtol=1e-5)
l_max=3, m_max=3) sphere2 = part.Sphere(position=[-200, -200, 300], refractive_index=2.4 + 0.0j, radius=120, l_max=3, m_max=3) sphere3 = part.Sphere(position=[-200, 200, 300], refractive_index=2.5 + 0.0j, radius=90, l_max=3, m_max=3) part_list = [sphere1, sphere2, sphere3] # initialize layer system object lay_sys = lay.LayerSystem([0, 400, 0], [1 + 6j, 2.3, 1.5]) # initialize dipole object dipole = init.DipoleSource(vacuum_wavelength=ld, dipole_moment=D, position=rD) # run simulation simulation = simul.Simulation(layer_system=lay_sys, particle_list=part_list, initial_field=dipole) simulation.run() xarr = np.array([-300, 400, -100, 200]) yarr = np.array([200, -100, 400, 300]) zarr = np.array([-50, 200, 600, 700]) scat_fld_exp = sf.scattered_field_piecewise_expansion(ld, part_list, lay_sys)
z = [1, 13, -43, 0] # initialize particle objects diel_sphere = part.Sphere(position=[0, 0, 0], refractive_index=n_glass, radius=sphere_radius, l_max=lmax, m_max=lmax) metal_sphere = part.Sphere(position=[0, 0, 0], refractive_index=n_metal, radius=sphere_radius, l_max=lmax, m_max=lmax) # initialize layer system objects lay_sys_air = lay.LayerSystem([0, 0], [n_air, n_air]) lay_sys_water = lay.LayerSystem([0, 0], [n_water, n_water]) # initialize initial field object init_fld = init.PlaneWave(vacuum_wavelength=vacuum_wavelength, polar_angle=0, azimuthal_angle=0, polarization=0, amplitude=1, reference_point=[0, 0, 0]) # simulation of dielectric sphere simulation_diel = sim.Simulation( layer_system=lay_sys_air, particle_list=[diel_sphere], initial_field=init_fld,
farfield_neff_discr = 1e-2 # -------------------------------------------- coord.set_default_k_parallel(vacuum_wavelength, neff_waypoints, neff_discr) # initialize particle object part1 = part.Sphere(position=[0, 0, distance_sphere_substrate + sphere_radius], refractive_index=sphere_refractive_index, radius=sphere_radius, l_max=lmax, m_max=lmax) particle_list = [part1] # initialize layer system object lay_sys = lay.LayerSystem( [0, 0], [substrate_refractive_index, surrounding_medium_refractive_index]) # initialize initial field object init_fld = init.PlaneWave(vacuum_wavelength=vacuum_wavelength, polar_angle=plane_wave_polar_angle, azimuthal_angle=plane_wave_azimuthal_angle, polarization=plane_wave_polarization, amplitude=plane_wave_amplitude, reference_point=[0, 0, 0]) # simulation simulation = sim.Simulation(layer_system=lay_sys, particle_list=particle_list, initial_field=init_fld) simulation.run()
l_max=3, m_max=3) sphere2 = part.Sphere(position=[-200, -200, 300], refractive_index=2.4 + 0.0j, radius=120, l_max=3, m_max=3) sphere3 = part.Sphere(position=[-200, 200, 300], refractive_index=2.5 + 0.0j, radius=90, l_max=3, m_max=3) part_list = [sphere1, sphere2, sphere3] # initialize layer system object lay_sys = lay.LayerSystem([0, 400, 0], [2, 1.3, 2]) # initialize dipole object dipole = init.DipoleSource(vacuum_wavelength=ld, dipole_moment=D, position=rD) # run simulation simulation = simul.Simulation(layer_system=lay_sys, particle_list=part_list, initial_field=dipole) simulation.run() power_hom = dipole.dissipated_power_homogeneous_background( layer_system=simulation.layer_system) power = dipole.dissipated_power(particle_list=simulation.particle_list, layer_system=simulation.layer_system) power2 = dipole.dissipated_power_alternative(
l_max=3, m_max=3) sphere2 = part.Sphere(position=[102, -100, 150], refractive_index=1.9 + 0.2j, radius=80, l_max=3, m_max=2) sphere3 = part.Sphere(position=[202, 100, 150], refractive_index=1.7 + 0.0j, radius=90, l_max=3, m_max=3) particle_list = [sphere1, sphere2, sphere3] # initialize layer system object lay_sys = lay.LayerSystem([0, 400, 0], [1.5, 2 + 0.01j, 1]) phi12 = np.arctan2(sphere1.position[1] - sphere2.position[1], sphere1.position[0] - sphere2.position[0]) rho12 = np.sqrt( sum([(sphere1.position[i] - sphere2.position[i])**2 for i in range(3)])) wr12 = coup.layer_mediated_coupling_block(vacuum_wavelength, sphere1, sphere2, lay_sys) w12 = coup.direct_coupling_block(vacuum_wavelength, sphere1, sphere2, lay_sys) phi13 = np.arctan2(sphere1.position[1] - sphere3.position[1], sphere1.position[0] - sphere3.position[0]) rho13 = np.sqrt( sum([(sphere1.position[i] - sphere3.position[i])**2 for i in range(3)])) wr13 = coup.layer_mediated_coupling_block(vacuum_wavelength, sphere1, sphere3, lay_sys)
rD = [300, -200, 100] D = [1e7, 2e7, 3e7] thick = [0, 200, 200, 0] n = [1, 1.5, 2 + 1e-2j, 1 + 5j] waypoints = [0, 0.8, 0.8 - 0.1j, 2.1 - 0.1j, 2.1, 4] neff_discr = 1e-2 rS = [100, 200, 300] nS = 1.5 RS = 100 # -------------------------------------------- coord.set_default_k_parallel(vacuum_wavelength=ld, neff_waypoints=waypoints, neff_resolution=neff_discr) dipole = init.DipoleSource(vacuum_wavelength=ld, dipole_moment=D, position=rD) laysys = lay.LayerSystem(thicknesses=thick, refractive_indices=n) particle = smuthi.particles.Sphere(position=rS, l_max=3, m_max=3, refractive_index=nS, radius=RS) simulation = simul.Simulation(layer_system=laysys, particle_list=[particle], initial_field=dipole) aI = dipole.spherical_wave_expansion(particle, laysys) def test_SWE_coefficients_against_prototype(): aI0 = -0.042563330382109 - 1.073039889335632j err0 = abs((aI.coefficients[0] - aI0) / aI0)
def read_input_yaml(filename): """Parse input file Args: filename (str): relative path and filename of input file Returns: smuthi.simulation.Simulation object containing the params of the input file """ print('Reading ' + os.path.abspath(filename)) with open(filename, 'r') as input_file: input_data = yaml.load(input_file.read()) cu.enable_gpu(input_data.get('enable GPU', False)) # wavelength wl = float(input_data['vacuum wavelength']) # set default coordinate arrays angle_unit = input_data.get('angle unit') if angle_unit == 'degree': angle_factor = np.pi / 180 else: angle_factor = 1 angle_resolution = input_data.get( 'angular resolution', np.pi / 180 / angle_factor) * angle_factor coord.default_azimuthal_angles = np.arange( 0, 2 * np.pi + angle_resolution / 2, angle_resolution) coord.default_polar_angles = np.arange(0, np.pi + angle_resolution / 2, angle_resolution) neff_resolution = float(input_data.get('n_effective resolution', 1e-2)) neff_max = input_data.get('max n_effective') if neff_max is None: ref_ind = [ float(n) for n in input_data['layer system']['refractive indices'] ] neff_max = max(np.array(ref_ind).real) + 1 neff_imag = float(input_data.get('n_effective imaginary deflection', 5e-2)) coord.set_default_k_parallel(vacuum_wavelength=wl, neff_resolution=neff_resolution, neff_max=neff_max, neff_imag=neff_imag) # initialize simulation lookup_resolution = input_data.get('coupling matrix lookup resolution', None) if lookup_resolution is not None and lookup_resolution <= 0: lookup_resolution = None simulation = smuthi.simulation.Simulation( solver_type=input_data.get('solver type', 'LU'), solver_tolerance=float(input_data.get('solver tolerance', 1e-4)), store_coupling_matrix=input_data.get('store coupling matrix', True), coupling_matrix_lookup_resolution=lookup_resolution, coupling_matrix_interpolator_kind=input_data.get( 'interpolation order', 'linear'), input_file=filename, length_unit=input_data.get('length unit'), output_dir=input_data.get('output folder'), save_after_run=input_data.get('save simulation')) # particle collection particle_list = [] particle_input = input_data['scattering particles'] if isinstance(particle_input, str): particle_type = 'sphere' with open(particle_input, 'r') as particle_specs_file: for line in particle_specs_file: if len(line.split()) > 0: if line.split()[-1] == 'spheres': particle_type = 'sphere' elif line.split()[-1] == 'spheroids': particle_type = 'spheroid' elif line.split()[-1] == 'cylinders': particle_type = 'finite cylinder' if not line.split()[0] == '#': numeric_line_data = [float(x) for x in line.split()] pos = numeric_line_data[:3] if particle_type == 'sphere': r = numeric_line_data[3] n = numeric_line_data[4] + 1j * numeric_line_data[5] l_max = int(numeric_line_data[6]) m_max = int(numeric_line_data[7]) particle_list.append( part.Sphere(position=pos, refractive_index=n, radius=r, l_max=l_max, m_max=m_max)) if particle_type == 'spheroid': c = numeric_line_data[3] a = numeric_line_data[4] beta = numeric_line_data[5] alpha = numeric_line_data[6] n = numeric_line_data[7] + 1j * numeric_line_data[8] l_max = int(numeric_line_data[9]) m_max = int(numeric_line_data[10]) particle_list.append( part.Spheroid(position=pos, polar_angle=beta, azimuthal_angle=beta, refractive_index=n, semi_axis_c=c, semi_axis_a=a, l_max=l_max, m_max=m_max)) if particle_type == 'finite cylinder': r = numeric_line_data[3] h = numeric_line_data[4] beta = numeric_line_data[5] alpha = numeric_line_data[6] n = numeric_line_data[7] + 1j * numeric_line_data[8] l_max = int(numeric_line_data[9]) m_max = int(numeric_line_data[10]) particle_list.append( part.FiniteCylinder(position=pos, polar_angle=beta, azimuthal_angle=beta, refractive_index=n, cylinder_radius=r, cylinder_height=h, l_max=l_max, m_max=m_max)) else: for prtcl in input_data['scattering particles']: n = (float(prtcl['refractive index']) + 1j * float(prtcl['extinction coefficient'])) pos = [ float(prtcl['position'][0]), float(prtcl['position'][1]), float(prtcl['position'][2]) ] l_max = int(prtcl['l_max']) m_max = int(prtcl.get('m_max', l_max)) if prtcl['shape'] == 'sphere': r = float(prtcl['radius']) particle_list.append( part.Sphere(position=pos, refractive_index=n, radius=r, l_max=l_max, m_max=m_max)) else: nfmds_settings = prtcl.get('NFM-DS settings', {}) use_ds = nfmds_settings.get('use discrete sources', True) nint = nfmds_settings.get('nint', 200) nrank = nfmds_settings.get('nrank', l_max + 2) t_matrix_method = { 'use discrete sources': use_ds, 'nint': nint, 'nrank': nrank } polar_angle = prtcl.get('polar angle', 0) azimuthal_angle = prtcl.get('azimuthal angle', 0) if prtcl['shape'] == 'spheroid': c = float(prtcl['semi axis c']) a = float(prtcl['semi axis a']) particle_list.append( part.Spheroid(position=pos, polar_angle=polar_angle, azimuthal_angle=azimuthal_angle, refractive_index=n, semi_axis_a=a, semi_axis_c=c, l_max=l_max, m_max=m_max, t_matrix_method=t_matrix_method)) elif prtcl['shape'] == 'finite cylinder': h = float(prtcl['cylinder height']) r = float(prtcl['cylinder radius']) particle_list.append( part.FiniteCylinder(position=pos, polar_angle=polar_angle, azimuthal_angle=azimuthal_angle, refractive_index=n, cylinder_radius=r, cylinder_height=h, l_max=l_max, m_max=m_max, t_matrix_method=t_matrix_method)) else: raise ValueError( 'Currently, only spheres, spheroids and finite cylinders are implemented' ) simulation.particle_list = particle_list # layer system thick = [float(d) for d in input_data['layer system']['thicknesses']] ref_ind = [ float(n) for n in input_data['layer system']['refractive indices'] ] ext_coeff = [ float(n) for n in input_data['layer system']['extinction coefficients'] ] ref_ind = np.array(ref_ind) + 1j * np.array(ext_coeff) ref_ind = ref_ind.tolist() simulation.layer_system = lay.LayerSystem(thicknesses=thick, refractive_indices=ref_ind) # initial field infld = input_data['initial field'] if infld['type'] == 'plane wave': a = float(infld.get('amplitude', 1)) pol_ang = angle_factor * float(infld['polar angle']) az_ang = angle_factor * float(infld['azimuthal angle']) if infld['polarization'] == 'TE': pol = 0 elif infld['polarization'] == 'TM': pol = 1 else: raise ValueError('polarization must be "TE" or "TM"') ref = [ float(infld.get('reference point', [0, 0, 0])[0]), float(infld.get('reference point', [0, 0, 0])[1]), float(infld.get('reference point', [0, 0, 0])[2]) ] initial_field = init.PlaneWave(vacuum_wavelength=wl, polar_angle=pol_ang, azimuthal_angle=az_ang, polarization=pol, amplitude=a, reference_point=ref) elif infld['type'] == 'Gaussian beam': a = float(infld['amplitude']) pol_ang = angle_factor * float(infld['polar angle']) az_ang = angle_factor * float(infld['azimuthal angle']) if infld['polarization'] == 'TE': pol = 0 elif infld['polarization'] == 'TM': pol = 1 else: raise ValueError('polarization must be "TE" or "TM"') ref = [ float(infld['focus point'][0]), float(infld['focus point'][1]), float(infld['focus point'][2]) ] ang_res = infld.get('angular resolution', np.pi / 180 / ang_fac) * ang_fac bet_arr = np.arange(0, np.pi / 2, ang_res) if pol_ang <= np.pi: kparr = np.sin(bet_arr) * simulation.layer_system.wavenumber( layer_number=0, vacuum_wavelength=wl) else: kparr = np.sin(bet_arr) * simulation.layer_system.wavenumber( layer_number=-1, vacuum_wavelength=wl) wst = infld['beam waist'] aarr = np.concatenate([np.arange(0, 2 * np.pi, ang_res), [2 * np.pi]]) initial_field = init.GaussianBeam(vacuum_wavelength=wl, polar_angle=pol_ang, azimuthal_angle=az_ang, polarization=pol, beam_waist=wst, k_parallel_array=kparr, azimuthal_angles_array=aarr, amplitude=a, reference_point=ref) elif infld['type'] == 'dipole source': pos = [float(infld['position'][i]) for i in range(3)] mom = [float(infld['dipole moment'][i]) for i in range(3)] initial_field = init.DipoleSource(vacuum_wavelength=wl, dipole_moment=mom, position=pos) elif infld['type'] == 'dipole collection': initial_field = init.DipoleCollection(vacuum_wavelength=wl) dipoles = infld['dipoles'] for dipole in dipoles: pos = [float(dipole['position'][i]) for i in range(3)] mom = [float(dipole['dipole moment'][i]) for i in range(3)] dip = init.DipoleSource(vacuum_wavelength=wl, dipole_moment=mom, position=pos) initial_field.append(dip) simulation.initial_field = initial_field # post processing simulation.post_processing = pp.PostProcessing() if input_data.get('post processing'): for item in input_data['post processing']: if item['task'] == 'evaluate far field': simulation.post_processing.tasks.append(item) elif item['task'] == 'evaluate near field': simulation.post_processing.tasks.append(item) return simulation