Beispiel #1
0
def test_index_matched_interface(source, rtol):
    """
    An interface that is index-matched with the medium is identical to not having an interface (cross-section comparison)
    """
    interface = miepy.interface(medium, z=zpos)
    cluster = miepy.sphere_cluster(position=[0, 0, 0],
                                   radius=radius,
                                   material=material,
                                   medium=medium,
                                   lmax=2,
                                   source=source,
                                   interface=interface,
                                   wavelength=wavelength)
    C1 = np.array(cluster.cross_sections())

    cluster = miepy.sphere_cluster(position=[0, 0, 0],
                                   radius=radius,
                                   material=material,
                                   medium=medium,
                                   lmax=2,
                                   source=source,
                                   wavelength=wavelength)
    C2 = np.array(cluster.cross_sections())

    assert np.allclose(C1, C2, atol=0, rtol=1e-15)
Beispiel #2
0
def test_interface_z_translation(s1, s2, rtol):
    """
    Moving the source and particle is identical to moving the interface (cross-section comparison)
    """
    interface = miepy.interface(miepy.constant_material(index=1.7))
    cluster = miepy.sphere_cluster(position=[0, 0, -zpos],
                                   radius=radius,
                                   material=material,
                                   medium=medium,
                                   lmax=2,
                                   source=s1,
                                   interface=interface,
                                   wavelength=wavelength)
    C1 = np.array(cluster.cross_sections())

    interface = miepy.interface(miepy.constant_material(index=1.7), z=zpos)
    cluster = miepy.sphere_cluster(position=[0, 0, 0],
                                   radius=radius,
                                   material=material,
                                   medium=medium,
                                   lmax=2,
                                   source=s2,
                                   interface=interface,
                                   wavelength=wavelength)
    C2 = np.array(cluster.cross_sections())

    assert np.allclose(C1, C2, atol=0, rtol=rtol)
Beispiel #3
0
def test_medium_scaling_force(plot=False):
    """ensure that the radiation pressure on a single sphere scales with 
       background index as n^5 for small, high-index sphere"""

    n_b = np.linspace(1, 5, 10)
    F = np.zeros_like(n_b)
    for i, n in enumerate(n_b):
        sphere = miepy.sphere_cluster(
            position=[0, 0, 0],
            radius=2 * nm,
            material=miepy.constant_material(40**2),
            medium=miepy.constant_material(n**2),
            source=miepy.sources.plane_wave.from_string(polarization='x'),
            wavelength=2800 * nm,
            lmax=2)

        F[i] = sphere.force_on_particle(0)[2]

    F_fit = np.max(F) * (n_b / np.max(n_b))**5

    if not plot:
        L2 = np.linalg.norm(F - F_fit) / F.shape[0]
        avg = np.average(F + F_fit) / 2
        print(L2, avg)
        assert L2 < 1e-2 * avg
    else:
        plt.figure()
        plt.plot(n_b, F, label='exact force')
        plt.plot(n_b, F_fit, 'o', label='$n_b^5$ scaling')
        plt.xlabel('$n_b$')
        plt.ylabel('force')
        plt.legend()
        plt.title(test_medium_scaling_force.__name__, weight='bold')
Beispiel #4
0
def test_sphere_cluster_tmatrix_particle():
    """sphere_cluster_particle in miepy.cluster yields the same results as miepy.sphere_cluster"""
    L = 155*nm
    lmax = 6

    cluster = miepy.sphere_cluster(position=[[-L/2, 0,0], [L/2,0,0]],
                                   material=Ag,
                                   radius=75*nm,
                                   source=source,
                                   lmax=lmax,
                                   medium=medium,
                                   wavelength=800*nm)
    C1 = cluster.cross_sections()
    cluster.solve_cluster_coefficients()
    p1 = cluster.p_cluster

    particle = miepy.sphere_cluster_particle(cluster.position, cluster.radius, Ag, lmax=lmax)
    cluster = miepy.cluster(particles=particle,
                            source=source,
                            lmax=lmax,
                            medium=medium,
                            wavelength=800*nm)
    C2 = cluster.cross_sections()
    p2 = cluster.p_scat

    assert np.allclose(C1, C2, rtol=7e-4, atol=0), 'equal cross-sections'
    assert np.allclose(p1, p2, rtol=1e-2, atol=1e-12), 'equal cluster scattering coefficients'
def test_cross_section_methods_monomer(plot=False):
    """test two cross-section methods for a single particle (monomer)"""
    C1 = np.zeros_like(wavelengths)
    C2 = np.zeros([len(wavelengths), 2, 2])

    for i, wavelength in enumerate(tqdm(wavelengths)):
        cluster = miepy.sphere_cluster(
            position=[0, 0, 0],
            radius=75 * nm,
            material=miepy.constant_material(3.7**2),
            source=miepy.sources.plane_wave.from_string(polarization='x'),
            lmax=2,
            wavelength=wavelength)

        C1[i] = cluster.cross_sections().scattering
        C2[i] = cluster.cross_sections_per_multipole().scattering
    C2_sum = np.sum(C2, axis=(1, 2))

    if not plot:
        L2 = np.linalg.norm(C1 - C2_sum) / C1.shape[0]
        avg = np.average(C1 + C2_sum) / 2
        print(L2, avg)
        assert L2 < 1e-4 * avg
    else:
        plt.figure()
        plt.plot(wavelengths / nm, C1, label='total scattering')
        plt.plot(wavelengths / nm, C2_sum, 'o', label='total scattering')
        plt.plot(wavelengths / nm, C2[:, 0, 0], label='eD')
        plt.plot(wavelengths / nm, C2[:, 1, 0], label='mD')
        plt.plot(wavelengths / nm, C2[:, 0, 1], label='eQ')
        plt.plot(wavelengths / nm, C2[:, 1, 1], label='mQ')

        plt.legend()
Beispiel #6
0
def test_boundary_conditions():
    """verifies the continunity of tangential components of E and H at the surface of a particle"""
    radius = 50 * nm

    cluster = miepy.sphere_cluster(
        position=[[0, 0, 0]],
        radius=radius,
        material=miepy.materials.Ag(),
        lmax=2,
        wavelength=600 * nm,
        source=miepy.sources.plane_wave.from_string(polarization='y'),
        medium=miepy.constant_material(1.2**2))

    theta = 0.3
    phi = 0.3
    eps = .1 * nm

    E_out = cluster.E_field(radius + eps, theta, phi, spherical=True)
    E_in = cluster.E_field(radius - eps, theta, phi, spherical=True)

    H_out = cluster.H_field(radius + eps, theta, phi, spherical=True)
    H_in = cluster.H_field(radius - eps, theta, phi, spherical=True)

    assert np.allclose(E_out[1:], E_in[1:], atol=4e-2, rtol=0)
    assert np.allclose(H_out[1:], H_in[1:], atol=4e-2, rtol=0)
Beispiel #7
0
def fields():
    pos = lattice[:]*600*nm
    # pos -= np.average(pos, axis=0)[np.newaxis]
    xmax = 100*nm
    pos = [[-xmax,-xmax,0], [xmax,xmax,0]]
    cluster = miepy.sphere_cluster(position=pos,
                                   radius=75*nm,
                                   material=Ag,
                                   source=source,
                                   wavelength=800*nm,
                                   lmax=lmax,
                                   medium=water)

    xmax = 500*nm
    x = np.linspace(-xmax, xmax, 250)
    y = np.linspace(-xmax, xmax, 250)
    X, Y = np.meshgrid(x, y)
    Z = np.zeros_like(X)

    E = cluster.E_field(X, Y, Z)
    Esrc = cluster.E_source(X, Y, Z)
    # enhance = np.linalg.norm(E, axis=0)/np.linalg.norm(Esrc, axis=0)
    enhance = np.linalg.norm(E, axis=0)**2

    return dict(enhance=enhance, X=X, Y=Y, E=E)
Beispiel #8
0
def test_cluster_field_near_to_far():
    """
    Compare scattered E/H-field of a cluster in far field using near and far field expressions
    Expressions are expected to converge in the limit r -> infinity
    """
    x = np.linspace(-600 * nm, 600 * nm, 3)
    y = np.linspace(-600 * nm, 600 * nm, 3)

    cluster = miepy.sphere_cluster(position=[[xv, yv, 0] for xv in x
                                             for yv in y],
                                   radius=100 * nm,
                                   material=miepy.constant_material(index=2),
                                   wavelength=wav,
                                   source=miepy.sources.plane_wave([1, 1]),
                                   lmax=3)

    theta = np.linspace(0, np.pi, 5)
    phi = np.linspace(0, 2 * np.pi, 5)
    THETA, PHI = np.meshgrid(theta, phi)
    radius = np.ones_like(THETA)

    E1 = cluster.E_field(radius, THETA, PHI, spherical=True, source=False)
    E2 = cluster.E_angular(THETA, PHI, radius=radius, source=False)

    H1 = cluster.H_field(radius, THETA, PHI, spherical=True, source=False)
    H2 = cluster.H_angular(THETA, PHI, radius=radius, source=False)

    assert np.allclose(E1[0], 0, atol=1e-10), 'radial component of E goes to 0'
    assert np.allclose(E1[1:], E2, atol=0, rtol=1e-6), 'E converges'
    assert np.allclose(H1[0], 0, atol=1e-10), 'radial component of H goes to 0'
    assert np.allclose(H1[1:], H2, atol=0, rtol=1e-6), 'H converges'
Beispiel #9
0
def test_maxwells_equations_cluster_near_field(source):
    """
    Verify Maxwell's equations for a cluster at a point in the near field
    """
    cluster = miepy.sphere_cluster(position=[[-400 * nm, -200 * nm, 0],
                                             [200 * nm, 200 * nm, 100 * nm]],
                                   radius=100 * nm,
                                   material=miepy.constant_material(index=3.7),
                                   source=source,
                                   wavelength=wav,
                                   lmax=2)

    x0, y0, z0 = 0, 0, 0
    eps = .1 * nm

    x = np.linspace(x0, x0 + eps, 2)
    y = np.linspace(y0, y0 + eps, 2)
    z = np.linspace(z0, z0 + eps, 2)
    X, Y, Z = np.meshgrid(x, y, z, indexing='ij')

    E_grid = cluster.E_field(X, Y, Z)
    E = np.average(E_grid, axis=(1, 2, 3))
    divE = div(E_grid, eps)
    curlE = curl(E_grid, eps)

    H_grid = cluster.H_field(X, Y, Z, k)
    H = np.average(H_grid, axis=(1, 2, 3))
    divH = div(H_grid, eps)
    curlH = curl(H_grid, eps)

    assert np.abs(divE / (k * np.linalg.norm(E))) < 1e-6, 'div(E) = 0'
    assert np.abs(divH / (k * np.linalg.norm(H))) < 1e-6, 'div(H) = 0'
    assert np.allclose(curlE, 1j * k * H, atol=0, rtol=1e-6), 'curl(E) = ikH'
    assert np.allclose(curlH, -1j * k * E, atol=0, rtol=1e-6), 'curl(H) = -ikE'
Beispiel #10
0
def test_interactions_off(plot=False):
    """compare extinction of cluster to single Mie extinction with interactions disabled
            expect: E(cluster) = N*E(single) 
    """
    sep = 200 * nm

    C1, A1, E1 = [np.zeros_like(wavelengths, dtype=float) for i in range(3)]
    for i, wavelength in enumerate(wavelengths):
        sol = miepy.sphere_cluster(position=[[sep / 2, 0, 0], [-sep / 2, 0,
                                                               0]],
                                   radius=radius,
                                   material=Ag,
                                   source=source,
                                   wavelength=wavelength,
                                   lmax=lmax,
                                   interactions=False)

        C1[i], A1[i], E1[i] = sol.cross_sections()

    # single
    sphere = miepy.single_mie_sphere(radius, Ag, wavelengths, lmax)
    Cs, As, Es = sphere.cross_sections()

    if not plot:
        for a, b, tol in [(E1, 2 * Es, 1e-15)]:
            L2 = np.linalg.norm(a - b) / a.shape[0]
            avg = np.average(a + b) / 2
            print(L2, avg)
            assert L2 < tol * avg

    else:
        fig, ax = plt.subplots()
        ax.plot(wavelengths / nm, C1, color='C0', label='scattering (cluster)')
        ax.plot(wavelengths / nm, A1, color='C1', label='absorption (cluster)')
        ax.plot(wavelengths / nm, E1, color='C2', label='extinction (cluster)')

        ax.plot(wavelengths / nm,
                2 * Cs,
                'o',
                color='C0',
                label='scattering (N x single)')
        ax.plot(wavelengths / nm,
                2 * As,
                'o',
                color='C1',
                label='absorption (N x single)')
        ax.plot(wavelengths / nm,
                2 * Es,
                'o',
                color='C2',
                label='extinction (N x single)')

        ax.set(xlabel='wavelength (nm)',
               ylabel='cross-section',
               title='test_interactions_off')
        ax.legend()
Beispiel #11
0
def test_off_center_particle(plot=False):
    """make sure scattering by a sphere away from the origin is equal to scattering of a particle at the origin"""

    # at the origin
    C1, A1, E1, C2, A2, E2 = [
        np.zeros_like(wavelengths, dtype=float) for i in range(6)
    ]
    for i, wavelength in enumerate(wavelengths):
        sol = miepy.sphere_cluster(position=[0, 0, 0],
                                   radius=radius,
                                   material=Ag,
                                   source=source,
                                   wavelength=wavelength,
                                   lmax=lmax)

        C1[i], A1[i], E1[i] = sol.cross_sections()

        # displace sphere
        sol.update_position([40 * nm, 50 * nm, 60 * nm])
        C2[i], A2[i], E2[i] = sol.cross_sections()

    if not plot:
        for a, b, tol in [(C1, C2, 1e-15), (A1, A2, 1e-14), (E1, E2, 1e-15)]:
            L2 = np.linalg.norm(a - b) / a.shape[0]
            avg = np.average(a + b) / 2
            print(L2, avg)
            assert L2 < tol * avg

    else:
        fig, ax = plt.subplots()
        ax.plot(wavelengths / nm, C1, color='C0', label='scattering (origin)')
        ax.plot(wavelengths / nm, A1, color='C1', label='absorption (origin)')
        ax.plot(wavelengths / nm, E1, color='C2', label='extinction (origin)')

        ax.plot(wavelengths / nm,
                C2,
                'o',
                color='C0',
                label='scattering (displaced)')
        ax.plot(wavelengths / nm,
                A2,
                'o',
                color='C1',
                label='absorption (displaced)')
        ax.plot(wavelengths / nm,
                E2,
                'o',
                color='C2',
                label='extinction (displaced)')

        ax.set(xlabel='wavelength (nm)',
               ylabel='cross-section',
               title='test_off_center_particle')
        ax.legend()
def sim():
    cluster = miepy.sphere_cluster(position=initial,
                                   radius=radius,
                                   material=Ag,
                                   source=source,
                                   wavelength=wavelength,
                                   medium=water,
                                   lmax=2)

    bd = stoked_from_cluster_2d(cluster, dt=dt, temperature=300)

    for i in pbar(range(Nsteps)):
        if i % 10 == 0:
            yield dict(pos=bd.position)
        bd.step()
Beispiel #13
0
def tests(Nmax, step=1):
    Nparticles = np.arange(1, Nmax + 1, step)
    t_force, t_flux, t_build, t_solve, t_source = [
        np.zeros_like(Nparticles, dtype=float) for i in range(5)
    ]
    for i, N in enumerate(Nparticles):
        print(N, Nmax)
        # positions = [[n*separation, 0, 0] for n in range(N)]
        positions = hexagonal_lattice_particles(N) * separation
        mie = miepy.sphere_cluster(position=positions,
                                   radius=radius,
                                   material=Ag,
                                   source=source,
                                   wavelength=600 * nm,
                                   lmax=2)

        t_force[i] = time_function(mie.force)
        t_flux[i] = time_function(mie.cross_sections)
        t_build[i] = time_function(
            partial(miepy.interactions.sphere_aggregate_tmatrix, mie.position,
                    mie.mie_scat, mie.material_data.k_b))

        A = miepy.interactions.sphere_aggregate_tmatrix(
            mie.position, mie.mie_scat, k=mie.material_data.k_b)
        t_solve[i] = time_function(
            partial(solve_linear_system,
                    A,
                    mie.p_src,
                    method=miepy.solver.bicgstab))

        x = np.linspace(0, N * separation, 1)
        y = 2 * radius * np.ones_like(x)
        z = np.zeros_like(x)

        t_source[i] = time_function(mie._solve_source_decomposition)

    fig, ax = plt.subplots()

    ax.plot(Nparticles, t_force * 1e3, '-o', label='force')
    ax.plot(Nparticles, t_flux * 1e3, '-o', label='flux')
    ax.plot(Nparticles, t_build * 1e3, '-o', label='build')
    ax.plot(Nparticles, t_solve * 1e3, '-o', label='solve')
    ax.plot(Nparticles, t_source * 1e3, '-o', label='source')

    ax.legend()
    ax.set(xlabel='number of particles', ylabel='runtime (ms)')

    plt.show()
Beispiel #14
0
def test_maxwells_equations_cluster_far_field(source):
    """
    Verify Maxwell's equations for a cluster at a point in the far field
    """
    cluster = miepy.sphere_cluster(position=[[-400 * nm, -200 * nm, 0],
                                             [200 * nm, 200 * nm, 100 * nm]],
                                   radius=100 * nm,
                                   material=miepy.constant_material(index=3.7),
                                   source=source,
                                   wavelength=wav,
                                   lmax=2)

    x0, y0, z0 = 0, 0, 1
    eps = 1 * nm

    x = np.linspace(x0, x0 + eps, 2)
    y = np.linspace(y0, y0 + eps, 2)
    z = np.linspace(z0, z0 + eps, 2)
    X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
    R, THETA, PHI = miepy.coordinates.cart_to_sph(X, Y, Z)

    E_grid = cluster.E_angular(THETA, PHI, radius=R)
    E_grid = np.insert(E_grid, 0, 0, axis=0)
    E_grid = miepy.coordinates.vec_sph_to_cart(E_grid, THETA, PHI)

    E = np.average(E_grid, axis=(1, 2, 3))
    divE = div(E_grid, eps)
    curlE = curl(E_grid, eps)

    H_grid = cluster.H_angular(THETA, PHI, radius=R)
    H_grid = np.insert(H_grid, 0, 0, axis=0)
    H_grid = miepy.coordinates.vec_sph_to_cart(H_grid, THETA, PHI)

    H = np.average(H_grid, axis=(1, 2, 3))
    divH = div(H_grid, eps)
    curlH = curl(H_grid, eps)

    assert np.abs(divE / (k * np.linalg.norm(E))) < 1e-6, 'div(E) = 0'
    assert np.abs(divH / (k * np.linalg.norm(H))) < 1e-6, 'div(H) = 0'
    assert np.allclose(curlE[:2], 1j * k * H[:2], atol=0,
                       rtol=1e-5), 'curl(E) = ikH'
    assert np.allclose(curlH[:2], -1j * k * E[:2], atol=0,
                       rtol=1e-5), 'curl(H) = -ikE'
Beispiel #15
0
def tests(Nmax, step=1):
    Nparticles = np.arange(1, Nmax+1, step)
    names = ['build', 'solve', 'flux', 'force']
    ftimer = {name: np.zeros_like(Nparticles, dtype=float) for name in names}
    for i,N in enumerate(Nparticles):
        print(N, Nmax)
        positions = [[n*separation, 0, 0] for n in range(N)]
        mie = miepy.sphere_cluster(position=positions,
                                   radius=radius,
                                   material=Ag,
                                   source=source,
                                   wavelength=600*nm,
                                   lmax=2)
        
        ftimer['force'][i] = time_function(mie.force)
        ftimer['flux'][i] = time_function(mie.cross_sections)
        ftimer['build'][i] = time_function(partial(miepy.interactions.sphere_aggregate_tmatrix, 
                              mie.position, mie.mie_scat, mie.material_data.k_b))

        A = miepy.interactions.sphere_aggregate_tmatrix(mie.position, mie.mie_scat, k=mie.material_data.k_b)
        ftimer['solve'][i] = time_function(partial(solve_linear_system, A, mie.p_src, method=miepy.solver.bicgstab))

    return ftimer, Nparticles
Beispiel #16
0
def test_tmatrix_sphere_is_sphere(material, atol):
    """tmatrix method with spheres should be equivalent to sphere cluster"""

    position = [[-300*nm, 0, 0], [300*nm, 0, 0]]

    spheres = miepy.sphere_cluster(position=position,
                                   radius=radius,
                                   material=material,
                                   source=source,
                                   wavelength=wavelength,
                                   lmax=lmax,
                                   medium=medium)

    particles = [miepy.sphere(pos, radius, material) for pos in position]

    cluster = miepy.cluster(particles=particles,
                            source=source,
                            wavelength=wavelength,
                            lmax=lmax,
                            medium=medium)

    print(np.max(np.abs(spheres.p_inc - cluster.p_inc)))
    assert np.allclose(spheres.p_inc, cluster.p_inc, rtol=0, atol=atol)
Beispiel #17
0
S, A, E = sphere.cross_sections()
Fz = sphere.radiation_force()

# Generalized Mie Theory (GMT)
source = miepy.sources.plane_wave.from_string(polarization='x')

scat = np.zeros_like(wavelengths)
absorb = np.zeros_like(wavelengths)
extinct = np.zeros_like(wavelengths)
force = np.zeros((3, ) + wavelengths.shape)

for i, wavelength in enumerate(wavelengths):
    system = miepy.sphere_cluster(position=[0, 0, 0],
                                  radius=radius,
                                  material=dielectric,
                                  source=source,
                                  wavelength=wavelength,
                                  lmax=lmax,
                                  medium=medium)

    scat[i], absorb[i], extinct[i] = system.cross_sections()
    force[:, i] = system.force_on_particle(0)


def test_scattering():
    """compare scattering cross-section of GMT and single Mie theory"""
    L2 = np.linalg.norm(scat - S) / scat.shape[0]
    avg = np.average(np.abs(S) + np.abs(scat)) / 2

    assert np.all(L2 < 1e-15 * avg)
Beispiel #18
0
Ag = miepy.materials.Ag()
radius = 75*nm
source = miepy.sources.plane_wave.from_string(polarization='rhc', direction='-z')
lmax = 2
water = miepy.materials.water()

wavelength = 800*nm
separation = 600*nm
L = 1
lattice = hexagonal_lattice_layers(L)

cluster = miepy.sphere_cluster(position=separation*lattice,
                               radius=radius,
                               material=Ag,
                               source=source,
                               wavelength=wavelength,
                               lmax=lmax,
                               medium=water)
xmax = L*separation + 8*radius

x = np.linspace(-xmax, xmax, 100)
y = np.linspace(-xmax, xmax, 100)
X, Y = np.meshgrid(x, y)
Z = np.zeros_like(X)

E = cluster.E_field(X, Y, Z)
I = np.sum(np.abs(E)**2, axis=0)

fig, axes = plt.subplots(ncols=3, figsize=(15,6))
ax = axes[0]
Beispiel #19
0
		# 			save_opts=[{'format':'png'},
		# 						{'format':'raw'}],
		# 			outputdir=(projects_directory_location + "/smuthi_output_" + str( comparison + job_idx ) + "/"),
		# 			xmin=-1000,
		# 			xmax=1000,
		# 			ymin=-1000,
		# 			ymax=1000,
		# 			zmin=focal_length_nm,
		# 			zmax=focal_length_nm,
		# 			resolution_step=50,
		# 			simulation=simulation,
		# 			show_internal_field=False)


		mie_cluster = miepy.sphere_cluster(
			medium=background_dielectric,
			position=random_centers, radius=random_radii, material=random_materials,
			source=plane_wave, wavelength=(probe_wavelength_nm*nm), lmax=lmax )#, interface=air_interface )

		gmmt_data[ comparison + job_idx, 0 ] = np.sum(
			np.abs( mie_cluster.E_field( 0.25 * device_size_x_nm * nm, 0.25 * device_size_y_nm * nm, focal_z_nm * nm ) )**2 )
		gmmt_data[ comparison + job_idx, 1 ] = np.sum(
			np.abs( mie_cluster.E_field( -0.25 * device_size_x_nm * nm, 0.25 * device_size_y_nm * nm, focal_z_nm * nm ) )**2 )
		gmmt_data[ comparison + job_idx, 2 ] = np.sum(
			np.abs( mie_cluster.E_field( -0.25 * device_size_x_nm * nm, -0.25 * device_size_y_nm * nm, focal_z_nm * nm ) )**2 )
		gmmt_data[ comparison + job_idx, 3 ] = np.sum(
			np.abs( mie_cluster.E_field( 0.25 * device_size_x_nm * nm, -0.25 * device_size_y_nm * nm, focal_z_nm * nm ) )**2 )

		gmmt_focal_intensity[ comparison + job_idx ] = np.sum(
			np.abs( mie_cluster.E_field( focal_lateral_search_mesh_x_nm, focal_lateral_search_mesh_y_nm, focal_lateral_search_mesh_z_nm ) )**2,
			axis=0 )
		gmmt_focal_E[ comparison + job_idx ] = mie_cluster.E_field( focal_lateral_search_mesh_x_nm, focal_lateral_search_mesh_y_nm, focal_lateral_search_mesh_z_nm )
Beispiel #20
0
wavelengths = np.linspace(400 * nm, 1000 * nm, 40)
frequency = np.linspace(1, 1 / 0.4, 40)

separation = 400 * nm
radius = 75 * nm
Au = miepy.data_material(wavelengths, eps)
source = miepy.sources.plane_wave.from_string(polarization='rhc')
gmtF = np.zeros((3, ) + wavelengths.shape)
gmtC = np.zeros((3, ) + wavelengths.shape)

for i, wavelength in enumerate(wavelengths):
    sol = miepy.sphere_cluster(position=[[-separation / 2, 0, 0],
                                         [separation / 2, 0, 0]],
                               radius=radius,
                               material=Au,
                               source=source,
                               wavelength=wavelength,
                               lmax=2)

    gmtF[:, i] = sol.force_on_particle(1)
    gmtC[:, i] = sol.cross_sections()


def test_fdtd_cross_sections(plot=False):
    """compare cross-sections to fdtd"""
    if not plot:
        L2 = np.linalg.norm(scat - gmtC[0]) / scat.shape[0]
        assert np.all(L2 < 8e-15)

        L2 = np.linalg.norm(absorb - gmtC[1]) / absorb.shape[0]
Beispiel #21
0
"""
Far-field analysis with the GMT
"""

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib as mpl
import miepy

nm = 1e-9

sol = miepy.sphere_cluster(
    position=[[-100 * nm, 0, 0], [100 * nm, 0, 0]],
    radius=75 * nm,
    material=miepy.constant_material(3.6**2),
    source=miepy.sources.plane_wave.from_string(polarization='y'),
    wavelength=600 * nm,
    lmax=2)

### xy plane far-field
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})

r = 10000 * nm
phi = np.linspace(0, 2 * np.pi, 100)
theta = np.pi / 2

THETA, PHI = np.meshgrid(theta, phi, indexing='ij')
E = sol.E_angular(THETA, PHI).squeeze()
I = np.sum(np.abs(E)**2, axis=0)
Beispiel #22
0
Ag = miepy.materials.Ag()
radius = 75 * nm
source = miepy.sources.plane_wave.from_string(polarization='x')
separations = np.linspace(2 * radius + 10 * nm, 2 * radius + 200 * nm, 5)

analytic_scattering = np.zeros(separations.shape)
analytic_absorption = np.zeros(separations.shape)

poynting_scattering = np.zeros(separations.shape)
poynting_absorption = np.zeros(separations.shape)

for i, separation in enumerate(tqdm(separations)):
    mie = miepy.sphere_cluster(position=[[separation / 2, 0, 0],
                                         [-separation / 2, 0, 0]],
                               radius=radius,
                               material=Ag,
                               source=source,
                               wavelength=800 * nm,
                               lmax=1)

    analytic_scattering[i], analytic_absorption[i], _ = mie.cross_sections()

    poynting_scattering[i], poynting_absorption[
        i], _ = miepy.flux._gmt_cross_sections_from_poynting(
            mie, radius=separation + radius, sampling=60)


def test_scattering():
    """comapre analytic scattering to numerical Poynting vector approach"""
    L2 = np.linalg.norm(analytic_scattering -
                        poynting_scattering) / poynting_scattering.shape[0]
Beispiel #23
0
def test_medium_cross_sections(plot=False):
    """verify cross-sections of an Au dimer in water by comparing with Poynting vector approach"""
    Nwav = 5
    Au = miepy.materials.Au()
    radius = 50 * nm

    lmax = 2
    nb = 1.33
    medium = miepy.constant_material(nb**2)

    wavelengths = np.linspace(500 * nm, 1000 * nm, Nwav)
    separation = 2 * radius + 40 * nm
    source = miepy.sources.plane_wave.from_string(polarization='x')

    THETA, PHI = miepy.coordinates.sphere_mesh(20)
    R = (separation / 2 + radius + 20 * nm) * np.ones_like(THETA)
    X, Y, Z = miepy.coordinates.sph_to_cart(R, THETA, PHI)

    scat, absorb, extinct, C, A = (np.zeros_like(wavelengths)
                                   for i in range(5))
    for i, wavelength in enumerate(wavelengths):
        sol = miepy.sphere_cluster(position=[[separation / 2, 0, 0],
                                             [-separation / 2, 0, 0]],
                                   radius=radius,
                                   material=Au,
                                   source=source,
                                   medium=medium,
                                   wavelength=wavelength,
                                   lmax=lmax)

        scat[i], absorb[i], extinct[i] = sol.cross_sections()

        E = sol.E_field(X, Y, Z, source=False)
        H = sol.H_field(X, Y, Z, source=False)
        C[i] = miepy.flux.flux_from_poynting_sphere(E, H, R, eps=nb**2)

        E = sol.E_field(X, Y, Z, source=True)
        H = sol.H_field(X, Y, Z, source=True)
        A[i] = -miepy.flux.flux_from_poynting_sphere(E, H, R, eps=nb**2)

    if not plot:
        for a, b, tol in [(C, scat, 1e-3), (A, absorb, 1e-3),
                          (C + A, extinct, 1e-3)]:
            L2 = np.linalg.norm(a - b) / a.shape[0]
            avg = np.average(a + b) / 2
            print(L2, avg)
            assert L2 < tol * avg
    else:
        plt.figure()
        line, = plt.plot(wavelengths / nm,
                         C,
                         'o',
                         color='C0',
                         label='scattering (Poynting)')
        line, = plt.plot(wavelengths / nm,
                         A,
                         'o',
                         color='C1',
                         label='absorbption (Poynting)')
        line, = plt.plot(wavelengths / nm,
                         C + A,
                         'o',
                         color='C2',
                         label='extinction (Poynting)')

        plt.axhline(color='black', linestyle='--')
        line, = plt.plot(wavelengths / nm,
                         scat,
                         color='C0',
                         label='scattering (analytic)')
        line, = plt.plot(wavelengths / nm,
                         absorb,
                         color='C1',
                         label='absorbption (analytic)')
        line, = plt.plot(wavelengths / nm,
                         extinct,
                         color='C2',
                         label='extinction (analytic)')

        plt.xlabel('wavelength (nm)')
        plt.ylabel(r'cross-section ($\mu$m$^2$)')
        plt.legend()
        plt.title(test_medium_cross_sections.__name__, weight='bold')