示例#1
0
    def E_field_from_particle(self, i, x, y, z, source=True):
        """Compute the electric field around particle i
             
            Arguments:
                i        particle number
                x        x position (array-like) 
                y        y position (array-like) 
                z        z position (array-like) 
                source   Include the source field (bool, default=True)

            Returns: E[3,...]
        """
        rad, theta, phi = miepy.coordinates.cart_to_sph(
            x, y, z, origin=self.position[i])

        E_sph = miepy.expand_E(self.p_scat[i],
                               self.material_data.k_b,
                               mode=miepy.vsh_mode.outgoing)(rad, theta, phi)
        Escat = miepy.coordinates.vec_sph_to_cart(E_sph, theta, phi)

        p = self.p_inc[i]
        if not source:
            p -= self.p_src[i]
        E_sph = miepy.expand_E(p,
                               self.material_data.k_b,
                               mode=miepy.vsh_mode.incident)(rad, theta, phi)
        Einc = miepy.coordinates.vec_sph_to_cart(E_sph, theta, phi)

        return Escat + Einc
示例#2
0
    def E_field(self, x1, x2, x3, interior=True, source=True, mask=False, far=False, spherical=False):
        """Compute the electric field due to all particles
             
            Arguments:
                x1        x/r position (array-like) 
                x2        y/theta position (array-like) 
                x3        z/phi position (array-like) 
                interior  (optional) compute interior fields (bool, default=True)
                source    (optional) include the source field (bool, default=True)
                mask      (optional) set interior fields to 0 (bool, default=False)
                far       (optional) use expressions valid only for far-field (bool, default=False)
                spherical (optional) input/output in spherical coordinates (bool, default=False)

            Returns: E[3,...]
        """
        x1, x2, x3 = (np.asarray(x) for x in (x1, x2, x3))
        shape = max(*[x.shape for x in (x1, x2, x3)], key=len)
        E = np.zeros((3,) + shape, dtype=complex)

        if spherical:
            (x, y, z) = miepy.coordinates.sph_to_cart(x1, x2, x3, origin=self.origin)
        else:
            (x, y, z) = (x1, x2, x3)

        if far:
            expand = miepy.expand_E_far
        else:
            expand = partial(miepy.expand_E, mode=miepy.vsh_mode.outgoing)

        for i in range(self.Nparticles):
            rad, theta, phi = miepy.coordinates.cart_to_sph(x, y, z, origin=self.position[i])
            E_sph = expand(self.p_scat[i], self.material_data.k_b)(rad,theta,phi)
            E += miepy.coordinates.vec_sph_to_cart(E_sph, theta, phi)

        if source:
            E += self.E_source(x, y, z, far=far, spherical=False)

        #TODO: what if x is scalar...
        if interior and not mask and not far:
            for i in range(self.Nparticles):
                x0, y0, z0 = self.position[i]
                idx = ((x - x0)**2 + (y - y0)**2 + (z - z0)**2 < self.particles[i].enclosed_radius()**2)
                k_int = 2*np.pi*self.material_data.n[i]/self.wavelength

                rad, theta, phi = miepy.coordinates.cart_to_sph(x, y, z, origin=self.position[i])
                E_sph = miepy.expand_E(self.p_int[i], k_int, 
                                mode=miepy.vsh_mode.interior)(rad[idx], theta[idx], phi[idx])
                E[:,idx] = miepy.coordinates.vec_sph_to_cart(E_sph, theta[idx], phi[idx])

        if mask and not far:
            for i in range(self.Nparticles):
                x0, y0, z0 = self.position[i]
                idx = ((x - x0)**2 + (y - y0)**2 + (z - z0)**2 < self.particles[i].enclosed_radius()**2)
                E[:,idx] = 0

        #TODO: does this depend on the origin?
        if spherical:
            E = miepy.coordinates.vec_cart_to_sph(E, theta=x2, phi=x3)
        
        return E
示例#3
0
def test_plane_wave_rotation():
    """
    A rotated plane-wave: analytic compared to rotated expansion coefficients
    """
    Nx = 6
    Ny = 6
    Nz = 6
    x = np.linspace(-100 * nm, 100 * nm, Nx)
    y = np.linspace(-100 * nm, 100 * nm, Nx)
    z = np.linspace(-100 * nm, 100 * nm, Ny)

    X, Y, Z = np.meshgrid(x, y, z, indexing='ij')
    Y = np.zeros_like(X)

    wavelength = 600 * nm
    k = 2 * np.pi / wavelength

    source = miepy.sources.plane_wave(polarization=[1, 0],
                                      theta=np.pi / 3,
                                      phi=np.pi / 2.7)
    E1 = source.E_field(X, Y, Z, k)

    lmax = 6
    R, THETA, PHI = miepy.coordinates.cart_to_sph(X, Y, Z)
    p_src = source.structure([0, 0, 0], k, lmax)
    Efunc = miepy.expand_E(p_src, k, mode=miepy.vsh_mode.incident)

    E2 = Efunc(R, THETA, PHI)
    E2 = miepy.coordinates.vec_sph_to_cart(E2, THETA, PHI)

    L2 = np.sqrt(np.sum(np.abs(E1 - E2)**2)) / np.product(X.shape)
    avg = np.average(np.abs(E1) + np.abs(E2)) / 2
    assert L2 < 7e-6 * avg
示例#4
0
    def test_power_spherically_ingoing_waves(self):
        """power by far-field integration of spherically ingoing waves"""
        lmax = 6
        radius = 1e6 * (2 * np.pi / k)

        p_src = self.source.structure([0, 0, 0], k, lmax)
        theta = np.linspace(np.pi / 2, np.pi, 20)
        phi = np.linspace(0, 2 * np.pi, 20)
        THETA, PHI = np.meshgrid(theta, phi)
        R = radius * np.ones_like(THETA)

        Efunc = miepy.expand_E(p_src / 2, k, miepy.vsh_mode.ingoing)
        E = Efunc(R, THETA, PHI)
        S = 0.5 / Z0 * np.sum(np.abs(E)**2, axis=0) * np.sin(THETA)
        P = radius**2 * trapz_2d(theta, phi, S.T).real

        assert np.allclose(P, self.power, rtol=.04)
示例#5
0
def test_stiching_by_expansion_gaussian_beam():
    """reconstruct the paraxial E-field by expanding over p_src in a 'stitched' together fashion"""

    source = miepy.sources.gaussian_beam(width=width,
                                         polarization=polarization,
                                         power=power)
    E1 = gaussian_paraxial(X, Y, Z, k)

    E2 = np.zeros_like(E1)
    for xi, xval in enumerate(x):
        for yi, yval in enumerate(y):
            for zi, zval in enumerate(z):
                z0 = 50 * nm
                p_src = source.structure([xval, yval, zval - z0], k, lmax=3)
                Efunc = miepy.expand_E(p_src, k, miepy.vsh_mode.incident)

                R, THETA, PHI = miepy.coordinates.cart_to_sph(0, 0, z0)
                E = Efunc(R, THETA, PHI)
                E = miepy.coordinates.vec_sph_to_cart(E, THETA, PHI)
                E2[xi, yi, zi] = E[0]

    assert np.allclose(E1, E2, rtol=8e-3, atol=0)
示例#6
0
    def test_power_2d_integration(self):
        """power by  integrating Poynting vector in 2D plane"""
        lmax = 6
        p_src = self.source.structure([0, 0, 0], k, lmax)
        a = 3000 * nm
        x = np.linspace(-a, a, 20)
        y = np.linspace(-a, a, 20)
        X, Y = np.meshgrid(x, y)
        R, THETA, PHI = miepy.coordinates.cart_to_sph(X, Y, 0)
        Efunc = miepy.expand_E(p_src, k, miepy.vsh_mode.incident)
        Hfunc = miepy.expand_H(p_src, k, miepy.vsh_mode.incident, 1, 1)
        E = Efunc(R, THETA, PHI)
        H = Hfunc(R, THETA, PHI)
        E = miepy.coordinates.vec_sph_to_cart(E, THETA, PHI)
        H = miepy.coordinates.vec_sph_to_cart(H, THETA, PHI) / Z0

        S = 0.5 * np.linalg.norm(np.cross(E, np.conjugate(H), axis=0), axis=0)
        S = 0.5 * np.cross(E, np.conjugate(H), axis=0)[2]
        # S = 0.5*np.sum(np.abs(E)**2, axis=0)

        P = trapz_2d(x, y, S).real

        assert np.allclose(P, self.power, rtol=.04)
示例#7
0
文件: interface.py 项目: shiqic/miepy
    I = np.sum(np.abs(E)**2, axis=0)

    import matplotlib.pyplot as plt
    fig, ax = plt.subplots()
    ax.pcolormesh(X, Z, I, vmin=0)
    ax.set_aspect('equal')

    fig, ax = plt.subplots()
    ax.plot(x, I[:, 0])
    ax.plot(x, 4 * np.sin(k1 * x)**2)

    fig, ax = plt.subplots()
    pos = [-1.5, 0, 0]
    lmax = 9
    p1 = incident.structure(pos, k1, lmax)
    p2 = reflected.structure(pos, k1, lmax)

    x = np.linspace(-1, 1, 100)
    z = np.linspace(-1, 1, 100)
    X, Z = np.meshgrid(x, z)
    Y = .1 * np.ones_like(X)
    RAD, THETA, PHI = miepy.coordinates.cart_to_sph(X, Y, Z)

    E = miepy.expand_E(p1 + p2, k1, miepy.vsh_mode.incident)(RAD, THETA, PHI)
    I = np.sum(np.abs(E)**2, axis=0)
    ax.pcolormesh(X, Z, I, vmin=0)
    ax.set_aspect('equal')

    plt.show()