Beispiel #1
0
def sphere_extinction_analytical(freqs, r):
    """Analytical expressions for a PEC sphere's extinction for plane wave
    with E = 1V/m

    Parameters
    ----------
    freqs : ndarray
        Frequencies at which to calculate
    r : real
        Radius of sphere
    """
    from scipy.special import sph_jnyn
    N = 40

    k0r = freqs*2*np.pi/c*r
    #scs = np.zeros(len(k0r))
    #scs_modal = np.zeros((len(k0r), N))
    ecs_kerker = np.zeros(len(k0r))

    for count, x in enumerate(k0r):
        jn, jnp, yn, ynp = sph_jnyn(N, x)
        h2n = jn - 1j*yn
        h2np = jnp - 1j*ynp
        a_n = ((x*jnp + jn)/(x*h2np + h2n))[1:]
        b_n = (jn/h2n)[1:]
        #scs[count] = 2*np.pi*sum((2*np.arange(1, N+1)+1)*(abs(a_n)**2 + abs(b_n)**2))/x**2 #
        #scs_modal[count] = 2*np.pi*(2*np.arange(1, N+1)+1)*(abs(a_n)**2 + abs(b_n)**2)/x**2 #
        ecs_kerker[count] = 2*np.pi*np.real(np.sum((2*np.arange(1, N+1)+1)*(a_n + b_n)))/x**2

    return ecs_kerker*r**2/eta_0
Beispiel #2
0
    def bessy(self, n, z):
        """Given order (n) and argument (z), computes mad bessel related junk.
        Argument can be a scalar or vector numeric.
        """
        #http://docs.scipy.org/doc/scipy/reference/special.html
        # Returns all orders of N for a single argument (ie if order is 5,
        # returns n=0,1,2,3,4 for arg z.  Pain in the ass actually...
        # sph_jnyn computes jn, derivjn, yn, derivyn in one pass

        jn, djn, yn, dyn = special.sph_jnyn(n,z) #Compute sph j/y in one pass
        i = 1j

        # Choose only the nth's bessel function 
        jn=complex(jn[n])  
        yn=complex(yn[n])
        djn=complex(djn[n])
        dyn=complex(dyn[n])

        hn=jn + i*yn      #VERIFIED!!!
        dhn=djn + i*dyn #Derivative (d/dp (j + iy)) = (dj + idy)

        Psi=z*jn
        dPsi=z*djn + jn  #Psi = p(jn)  DPsi= jn + p j'n    Chain rollin
        Zi=z*hn	          
        dZi=z*dhn + hn    
        Xi=-z*yn          #Xi=-i*(Zi + Psi)     Verified WORKING either way!
        dXi=-(z*dyn + yn) #dXi=-i*(dZi + dPsi)

        return(Psi, dPsi, Zi, dZi, Xi, dXi)
Beispiel #3
0
    def set_all_layers(self, lab):
        self.data_layers = [0]
        for bnd in lab.boundaries():
            r, rd, rdd = bnd.shape.R(self.knots)
            rdr = rd / r
            r2rd2 = r**2 + rd**2
            Rad = [0, {}, {}]
            Radd = [0, {}, {}]
            kis = [0, bnd.k1, bnd.k2]
            for i in [1, 2]:
                krs = kis[i] * r
                JY = array([special.sph_jnyn(self.n, kr)
                            for kr in krs])[:, :, :]
                Rad[i] = {
                    'j': JY[:, 0, :],
                    'h': JY[:, 0, :] + 1j * JY[:, 2, :]
                }
                Radd[i] = {
                    'j': JY[:, 1, :],
                    'h': JY[:, 1, :] + 1j * JY[:, 3, :]
                }

            self.data_layers.append({'ki': kis,\
                                     'r': r,\
                                     'rd': rd,\
                                     'rdd': rdd,\
                                     'rdr': rdr,\
                                     'r2rd2': r2rd2,\
                                     'Rad': Rad,\
                                     'Radd': Radd})
Beispiel #4
0
    def bessy(self, n, z):
        """Given order (n) and argument (z), computes mad bessel related junk.
        Argument can be a scalar or vector numeric.
        """
        #http://docs.scipy.org/doc/scipy/reference/special.html
        # Returns all orders of N for a single argument (ie if order is 5,
        # returns n=0,1,2,3,4 for arg z.  Pain in the ass actually...
        # sph_jnyn computes jn, derivjn, yn, derivyn in one pass

        jn, djn, yn, dyn = special.sph_jnyn(n, z)  #Compute sph j/y in one pass
        i = 1j

        # Choose only the nth's bessel function
        jn = complex(jn[n])
        yn = complex(yn[n])
        djn = complex(djn[n])
        dyn = complex(dyn[n])

        hn = jn + i * yn  #VERIFIED!!!
        dhn = djn + i * dyn  #Derivative (d/dp (j + iy)) = (dj + idy)

        Psi = z * jn
        dPsi = z * djn + jn  #Psi = p(jn)  DPsi= jn + p j'n    Chain rollin
        Zi = z * hn
        dZi = z * dhn + hn
        Xi = -z * yn  #Xi=-i*(Zi + Psi)     Verified WORKING either way!
        dXi = -(z * dyn + yn)  #dXi=-i*(dZi + dPsi)

        return (Psi, dPsi, Zi, dZi, Xi, dXi)
Beispiel #5
0
 def get_phase_shift_from_logder(self,logder,E,r):
     k = np.sqrt(2*self.mass*E)
     kr = k*r
     jl, jlp, yl, ylp = sph_jnyn(0,kr)
     iyl = 1j*yl
     iylp = 1j*ylp
     sl = -(jl-iyl)/(jl+iyl) * (logder-kr*(jlp-iylp)/(jl-iyl))/(logder-kr*(jlp+iylp)/(jl+iyl))
     return np.angle(sl)/2.
Beispiel #6
0
 def get_phase_shift_from_logder(self, logder, E, r):
     k = np.sqrt(2 * self.mass * E)
     kr = k * r
     jl, jlp, yl, ylp = sph_jnyn(0, kr)
     iyl = 1j * yl
     iylp = 1j * ylp
     sl = -(jl - iyl) / (jl + iyl) * (logder - kr * (jlp - iylp) /
                                      (jl - iyl)) / (logder - kr *
                                                     (jlp + iylp) /
                                                     (jl + iyl))
     return np.angle(sl) / 2.
Beispiel #7
0
def jnyn( n, resolution ):
    delta = numpy.pi / resolution
    zTable = numpy.mgrid[delta:max( maxz_j( n ), maxz_y( n ) ):delta]

    jTable = numpy.zeros( ( len( zTable ), n + 1 ) )
    yTable = numpy.zeros( ( len( zTable ), n + 1 ) )
    for i, z in enumerate( zTable ):
        jTable[i], _, yTable[i], _ = special.sph_jnyn( n, z )

    jTable = jTable.transpose()
    yTable = yTable.transpose()
    return zTable, jTable, yTable
Beispiel #8
0
def riccati_2(nmax, x):
    """Riccati bessel function of the 2nd kind

       returns (r2, r2'), n=0,1,...,nmax"""

    jn, jnp, yn, ynp = special.sph_jnyn(nmax, x)
    hn = jn + 1j * yn
    hnp = jnp + 1j * ynp

    r0 = x * hn
    r1 = hn + x * hnp
    return np.array([r0, r1])
Beispiel #9
0
def calculate_mie_coefficients(n_max, x, m):
    """
    Calculates the Mie coefficients.

    :rtype : object
    :param n_max:
    :param x: size parameter
    :param m:
    """

    # calculate spherical bessels #
    jn, djn, yn, dyn = sph_jnyn(n_max, x)  # j(n, x), y(n, x)
    jm, djm, ym, dym = sph_jnyn(n_max, m * x)  # j(n, mx), y(n, mx)
    # calculate spherical hankel #
    hn, dhn = sph_hn(n_max, x)  # h(n, x)
    # calculate riccati bessel functions #
    dpsi_n = [x * jn[n - 1] - n * jn[n] for n in range(0, len(jn))]
    dpsi_m = [m * x * jm[n - 1] - n * jm[n] for n in range(0, len(jm))]
    dzeta_n = [x * hn[n - 1] - n * hn[n] for n in range(0, len(hn))]

    a_n = (m**2 * jm * dpsi_n - jn * dpsi_m) / (m**2 * jm * dzeta_n -
                                                hn * dpsi_m)
    b_n = (jm * dpsi_n - jn * dpsi_m) / (jm * dzeta_n - hn * dpsi_m)
    return a_n, b_n
Beispiel #10
0
def _mie_abcd(m, x):
    '''Computes a matrix of Mie coefficients, a_n, b_n, c_n, d_n,
    of orders n=1 to nmax, complex refractive index m=m'+im",
    and size parameter x=k0*a, where k0= wave number
    in the ambient medium, a=sphere radius;
    p. 100, 477 in Bohren and Huffman (1983) BEWI:TDD122
    C. Matzler, June 2002'''

    nmax = np.round(2+x+4*x**(1.0/3.0))
    mx = m * x

    # Get the spherical bessel functions of the first (j) and second (y) kind,
    # and their derivatives evaluated at x at order up to nmax
    j_x,jd_x,y_x,yd_x = ss.sph_jnyn(nmax, x)

    # The above function includes the 0 order bessel functions, which aren't used
    j_x = j_x[1:]
    jd_x = jd_x[1:]
    y_x = y_x[1:]
    yd_x = yd_x[1:]

    # Get the spherical Hankel function of the first type (and it's derivative)
    # from the combination of the bessel functions
    h1_x = j_x + 1.0j*y_x
    h1d_x = jd_x + 1.0j*yd_x

    # Get the spherical bessel function of the first kind and it's derivative
    # evaluated at mx
    j_mx,jd_mx = ss.sph_jn(nmax, mx)
    j_mx = j_mx[1:]
    jd_mx = jd_mx[1:]

    # Get primes (d/dx [x*f(x)]) using derivative product rule
    j_xp = j_x + x*jd_x
    j_mxp = j_mx + mx*jd_mx
    h1_xp = h1_x + x*h1d_x

    m2 = m * m
    an = (m2 * j_mx * j_xp - j_x * j_mxp)/(m2 * j_mx * h1_xp - h1_x * j_mxp)
    bn = (j_mx * j_xp - j_x * j_mxp)/(j_mx * h1_xp - h1_x * j_mxp)
##    cn = (j_x * h1_xp - h1_x * j_xp)/(j_mx * h1_xp - h1_x * j_mxp)
##    dn = m * (j_x * h1_xp - h1_x * j_xp)/(m2 * j_mx * h1_xp -h1_x * j_mxp)
    return an, bn
Beispiel #11
0
def jnyn(n, resolution):

    delta = numpy.pi / resolution
    z_table = numpy.mgrid[min(minz_j(n),minz_y(n)):max(maxz_j(n), maxz_y(n)):delta]

    j_table = numpy.zeros((len(z_table), n+1))
    jdot_table = numpy.zeros((len(z_table), n+1))
    y_table = numpy.zeros((len(z_table), n+1))
    ydot_table = numpy.zeros((len(z_table), n+1))

    for i, z in enumerate(z_table):
        j_table[i], jdot_table[i], y_table[i], ydot_table[i] \
            = special.sph_jnyn(n, z)

    j_table = j_table.transpose()
    jdot_table = jdot_table.transpose()
    y_table = y_table.transpose()
    ydot_table = ydot_table.transpose()
    return z_table, j_table, jdot_table, y_table, ydot_table
Beispiel #12
0
    def set_all_layers(self, lab):
        self.data_layers = [0]
        for bnd in lab.boundaries():
            r, rd, rdd = bnd.shape.R(self.knots)
            rdr = rd / r
            r2rd2 = r ** 2 + rd ** 2
            Rad = [0, {}, {}]
            Radd = [0, {}, {}]
            kis = [0, bnd.k1, bnd.k2]
            for i in [1, 2]:
                krs = kis[i] * r
                JY = array([special.sph_jnyn(self.n, kr) for kr in krs])[:, :, :]
                Rad[i] = {'j': JY[:, 0, :], 'h': JY[:, 0, :] + 1j * JY[:, 2, :]}
                Radd[i] = {'j': JY[:, 1, :], 'h': JY[:, 1, :] + 1j * JY[:, 3, :]}

            self.data_layers.append({'ki': kis,\
                                     'r': r,\
                                     'rd': rd,\
                                     'rdd': rdd,\
                                     'rdr': rdr,\
                                     'r2rd2': r2rd2,\
                                     'Rad': Rad,\
                                     'Radd': Radd})
Beispiel #13
0
def mie_abcd(m, x):
    """Computes a matrix of Mie coefficients, a_n, b_n, c_n, d_n,
    of orders n=1 to nmax, complex refractive index m=m'+im",
    and size parameter x=k0*a, where k0= wave number
    in the ambient medium, a=sphere radius;
    p. 100, 477 in Bohren and Huffman (1983) BEWI:TDD122
    C. Matzler, June 2002

    Inputs:
        - m  - scalar, refractive-index;
        - x  - 1D array, size parameter;

    Outputs:
        - an - 1D array, Mie coefficient;
        - bn - 1D array, Mie coefficient.

    Example:
        >>> import scipy.special as ss
        >>> m = 5.62 + 2.78j     # refractive index of water at 20 [Celsius]
        >>> d = 0.003            # drop diameter - 3 [mm] --> 0.003 [m]
        >>> lam = 0.01           # wavelength -   10 [mm] --> 0.01  [m]
        >>> x = np.pi * d / lam
        >>> an, bn = mie_abcd(m, x)
        >>> an
        array([  3.28284411e-01 -3.36266733e-01j,
                 3.55370117e-03 -2.36426920e-02j,
                 3.90046294e-05 -5.15173202e-04j,
                 3.89223349e-07 -6.78235070e-06j,
                 2.94035836e-09 -5.85429913e-08j,
                 1.66462864e-11 -3.54797147e-10j,   7.17772878e-14 -1.58903782e-12j])
        >>> bn
        array([  7.69466132e-02 +1.28116779e-01j,
                 6.75408598e-03 +6.94984812e-03j,
                 1.99953419e-04 +8.05215919e-05j,
                 2.23969208e-06 +8.10161445e-08j,
                 1.39633882e-08 -2.58644268e-09j,
                 6.06975879e-11 -1.97461249e-11j,   2.01460986e-13 -8.42856046e-14j])
    """

    nmax = np.round(2 + x + 4 * x ** (1.0 / 3.0))
    mx = m * x

    # Get the spherical bessel functions of the first (j) and second (y) kind,
    # and their derivatives evaluated at x at order up to nmax
    j_x, jd_x, y_x, yd_x = ss.sph_jnyn(nmax, x)

    # The above function includes the 0 order bessel functions, which aren't used
    j_x = j_x[1:]
    jd_x = jd_x[1:]
    y_x = y_x[1:]
    yd_x = yd_x[1:]

    # Get the spherical Hankel function of the first type (and it's derivative)
    # from the combination of the bessel functions
    h1_x = j_x + 1.0j * y_x
    h1d_x = jd_x + 1.0j * yd_x

    # Get the spherical bessel function of the first kind and it's derivative
    # evaluated at mx
    j_mx, jd_mx = ss.sph_jn(nmax, mx)
    j_mx = j_mx[1:]
    jd_mx = jd_mx[1:]

    # Get primes (d/dx [x*f(x)]) using derivative product rule
    j_xp = j_x + x * jd_x
    j_mxp = j_mx + mx * jd_mx
    h1_xp = h1_x + x * h1d_x

    m2 = m * m
    an = (m2 * j_mx * j_xp - j_x * j_mxp) / (m2 * j_mx * h1_xp - h1_x * j_mxp)
    bn = (j_mx * j_xp - j_x * j_mxp) / (j_mx * h1_xp - h1_x * j_mxp)
    return an, bn
Beispiel #14
0
def sph_hn(n, x):
    # calculate spherical hankel, h(n,x) = j(n,x) + iy(n,x) #
    jn, djn, yn, dyn = sph_jnyn(n, x)
    hn = jn + 1j * yn
    dhn = djn + 1j * dyn
    return hn, dhn
Beispiel #15
0
def get_JnHn(n, x):
    JnYn = array([special.sph_jnyn(n, xl) for xl in x])
    return JnYn[:, :2, :], JnYn[:, :2, :] + 1j * JnYn[:, 2:, :]
Beispiel #16
0
def get_JnHn(n, x):
    JnYn = array([special.sph_jnyn(n, xl) for xl in x])
    return JnYn[:, :2, :], JnYn[:, :2, :] + 1j * JnYn[:, 2:, :]