Пример #1
0
def test_rotated_spheroid_equals_rotated_light(material, atol):
    """cross-sections are the same if a spheroid is rotated or if the light is rotated"""

    theta = 1.3
    phi = 0.7

    source = miepy.sources.plane_wave([1,0], theta=theta, phi=phi)
    z_oriented = miepy.cluster(particles=miepy.spheroid([0,0,0], radius, 2*radius, material),
                               source=source,
                               wavelength=wavelength,
                               lmax=lmax,
                               medium=medium)

    C1 = z_oriented.cross_sections()

    source = miepy.sources.plane_wave([1,0])
    q = miepy.quaternion.from_spherical_coords(theta, phi).inverse()
    oriented = miepy.cluster(particles=miepy.spheroid([0,0,0], radius, 2*radius, material, orientation=q),
                             source=source,
                             wavelength=wavelength,
                             lmax=lmax,
                             medium=medium)

    C2 = oriented.cross_sections()

    assert np.allclose(C1, C2, rtol=0, atol=atol)
Пример #2
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'
Пример #3
0
def force_gmmt():
    wavelengths = np.linspace(400 * nm, 1000 * nm, 100)
    eps = meep_ext.get_eps(material)(wavelengths)
    Au = miepy.data_material(wavelengths, eps)
    # Au = miepy.constant_material(3.5**2)
    # Au = miepy.materials.Au()

    particles = []
    for i in range(9):
        orientation = miepy.quaternion.from_spherical_coords(theta[i], phi[i])
        particles.append(
            miepy.cylinder(position=[x[i], y[i], z[i]],
                           radius=radius,
                           height=height,
                           material=Au,
                           orientation=orientation))

    F = np.zeros([3, 9, len(wavelengths)], dtype=float)

    for i, wavelength in enumerate(pbar(wavelengths)):
        sol = miepy.cluster(particles=particles,
                            source=miepy.sources.plane_wave([1, 0]),
                            wavelength=wavelength,
                            lmax=4)

        F[..., i] = sol.force()
        # if i == 0:
        # miepy.visualize(sol)

    return dict(wavelengths=wavelengths, force=F)
Пример #4
0
def gmt_sim():
    material = miepy.materials.constant_material(3**2)

    q = miepy.quaternion.from_spherical_coords(0, 0)
    particles = [
        miepy.regular_prism([0, 0, 0],
                            4,
                            width=W,
                            height=H,
                            material=material,
                            orientation=q)
    ]

    c = miepy.cluster(particles=particles,
                      source=miepy.sources.plane_wave([1, 1j]),
                      wavelength=600 * nm,
                      lmax=8)

    x = np.linspace(-1.5 * W, 1.5 * W, 150)
    y = np.linspace(-1.5 * W, 1.5 * W, 150)
    X, Y = np.meshgrid(x, y)
    Z = np.zeros_like(X)
    E = c.E_field(X, Y, Z, mask=True)
    Ixy = np.sum(np.abs(E)**2, axis=0)

    R = particles[0].enclosed_radius() + 20 * nm
    phi = np.linspace(0, 2 * np.pi, 50)
    x = R * np.cos(phi)
    y = R * np.sin(phi)
    z = np.zeros_like(x)
    E = c.E_field(x, y, z)
    Iphi = np.sum(np.abs(E)**2, axis=0)

    return dict(phi=phi, X=X, Y=Y, Ixy=Ixy, Iphi=Iphi)
Пример #5
0
def force_gmmt():
    wavelengths = np.linspace(400 * nm, 1000 * nm, 100)
    # eps = meep_ext.get_eps(material)(wavelengths)
    # Au = miepy.data_material(wavelengths, eps)
    material = miepy.constant_material(3.5**2)

    particles = [
        miepy.cube([-sep / 2, 0, 0], 200 * nm, material),
        miepy.cube([sep / 2, 0, 0], 200 * nm, material)
    ]

    F1 = np.zeros((3, ) + wavelengths.shape, dtype=float)
    F2 = np.zeros((3, ) + wavelengths.shape, dtype=float)

    for i, wavelength in enumerate(pbar(wavelengths)):
        c = miepy.cluster(particles=particles,
                          source=miepy.sources.plane_wave([1, 0]),
                          wavelength=wavelength,
                          lmax=4)

        q = miepy.quaternion.from_spherical_coords(0, 0)
        c.update(orientation=[q, q])
        F1[:, i] = c.force_on_particle(1)

        q = miepy.quaternion.from_spherical_coords(0, np.pi / 4)
        c.update(orientation=[q, q])
        F2[:, i] = c.force_on_particle(1)

    return dict(wavelengths=wavelengths, F1=F1, F2=F2)
Пример #6
0
def vis():
    fig, ax = plt.subplots()

    norm = job.load(norm_sim)
    scat = job.load(scat_sim)

    ax.plot((1 / nm) / norm.frequency,
            scat.scattering / norm.incident * norm.area,
            'o',
            color='C0',
            label='scattering (FDTD)')
    ax.plot((1 / nm) / norm.frequency,
            scat.absorption / norm.incident * norm.area,
            'o',
            color='C1',
            label='absorption (FDTD)')
    ax.plot((1 / nm) / norm.frequency,
            (scat.scattering + scat.absorption) / norm.incident * norm.area,
            'o',
            color='C2',
            label='extinction (FDTD)')

    wavelengths = np.linspace(400 * nm, 1000 * nm, 100)
    eps = meep_ext.get_eps(material)(wavelengths)
    Au = miepy.data_material(wavelengths, eps)
    # Au = miepy.constant_material(3.5**2)

    C, A, E = [np.zeros_like(wavelengths) for i in range(3)]

    particles = []
    for i in range(9):
        orientation = miepy.quaternion.from_spherical_coords(theta[i], phi[i])
        particles.append(
            miepy.cylinder(position=[x[i], y[i], z[i]],
                           radius=radius,
                           height=height,
                           material=Au,
                           orientation=orientation))

    for i, wavelength in enumerate(pbar(wavelengths)):
        sol = miepy.cluster(particles=particles,
                            source=miepy.sources.plane_wave([1, 0]),
                            wavelength=wavelength,
                            lmax=3)

        C[i], A[i], E[i] = sol.cross_sections()

    ax.axhline(0, linestyle='--', color='black')
    ax.plot(wavelengths / nm, C, color='C0', label='scattering (GMT)')
    ax.plot(wavelengths / nm, A, color='C1', label='absorption (GMT)')
    ax.plot(wavelengths / nm, E, color='C2', label='extinction (GMT)')

    ax.legend()
    ax.set(xlabel='wavelength (nm)', ylabel='cross-section')

    plt.show()
Пример #7
0
def gmt_sim():
    wavelengths = np.linspace(400 * nm, 1000 * nm, 100)
    eps = meep_ext.get_eps(material)(wavelengths)
    Au = miepy.data_material(wavelengths, eps)
    Au = miepy.constant_material(3.5**2)

    C, A, E = [np.zeros_like(wavelengths) for i in range(3)]

    particles = []
    # orientation = miepy.quaternion.from_spherical_coords(theta[i], phi[i])
    particles.append(miepy.cube([0, 0, 0], W, material=Au, orientation=q))

    for i, wavelength in enumerate(tqdm(wavelengths)):
        sol = miepy.cluster(particles=particles,
                            source=miepy.sources.plane_wave([1, 0]),
                            wavelength=wavelength,
                            lmax=4)

        C[i], A[i], E[i] = sol.cross_sections()

    return dict(wavelengths=wavelengths, C=C, A=A, E=E)
Пример #8
0
def tests(Nmax, step=1):
    Nparticles = np.arange(1, Nmax+1, step)
    t_force, t_flux, t_build, t_solve, t_expand, t_tmatrix = [np.zeros_like(Nparticles, dtype=float) for i in range(6)]
    for i,N in enumerate(Nparticles):
        print(N, Nmax)
        positions = [[n*separation, 0, 0] for n in range(N)]
        particles = [miepy.spheroid(pos, radius, 0.5*radius, Ag) for pos in positions]
        mie = miepy.cluster(particles=particles,
                                      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.particle_aggregate_tmatrix, 
                              mie.position, mie.tmatrix, mie.material_data.k_b))

        A = miepy.interactions.particle_aggregate_tmatrix(mie.position, mie.tmatrix, k=mie.material_data.k_b)
        t_solve[i] = time_function(partial(solve_linear_system, A, mie.p_src, method=miepy.solver.bicgstab))
        t_tmatrix[i] = time_function(partial(tmatrix_time, mie))
        
        x = np.linspace(0, N*separation, 1)
        y = 2*radius*np.ones_like(x)
        z = np.zeros_like(x)

        t_expand[i] = time_function(partial(mie.E_field, x, y, z))

    fig, ax = plt.subplots()

    ax.plot(Nparticles, t_force, label='force')
    ax.plot(Nparticles, t_flux, label='flux')
    ax.plot(Nparticles, t_build, label='build')
    ax.plot(Nparticles, t_solve, label='solve')
    ax.plot(Nparticles, t_expand, label='expand')
    ax.plot(Nparticles, t_tmatrix, label='tmatrix')

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

    plt.show()
Пример #9
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)