def A22(x_, a_, b_): b_sqrt = np.sqrt(b_) term1 = ((1. - a_) / 2. + 1. + cs_sqd) * x_**((1. - a_) / 2. - 1.) * ss.yv( (a_ - 1.) / 2., b_sqrt * x_) term2 = b_sqrt / 2. * x_**((1. - a_) / 2.) * (ss.yv( (a_ - 1.) / 2. - 1., b_sqrt * x_) - ss.yv( (a_ - 1.) / 2. + 1., b_sqrt * x_)) return term1 + term2
def func_for_findroot_sce_nwfet0(k1, tOX0, epsOX, epsS): """ Function to find k (Eq.(8) in the Ref.[1]) Normalized with radius R (tOX0=tOX/radius) """ k2 = k1 * (1 + tOX0) lhs = epsS * jv(1, k1) * (jv(0, k1) * yv(0, k2) - jv(0, k2) * yv(0, k1)) rhs = epsOX * (jv(1, k1) * yv(0, k2) - jv(0, k2) * yv(1, k1)) * jv(0, k1) return (lhs - rhs)
def CoreShell_ab(mCore,mShell,xCore,xShell): # http://pymiescatt.readthedocs.io/en/latest/forwardCS.html#CoreShell_ab m = mShell/mCore u = mCore*xCore v = mShell*xCore w = mShell*xShell mx = max(np.abs(mCore*xShell),np.abs(mShell*xShell)) nmax = np.round(2+xShell+4*(xShell**(1/3))) nmx = np.round(max(nmax,mx)+16) n = np.arange(1,nmax+1) nu = n+0.5 sv = np.sqrt(0.5*np.pi*v) sw = np.sqrt(0.5*np.pi*w) sy = np.sqrt(0.5*np.pi*xShell) pv = sv*jv(nu,v) pw = sw*jv(nu,w) py = sy*jv(nu,xShell) chv = -sv*yv(nu,v) chw = -sw*yv(nu,w) chy = -sy*yv(nu,xShell) p1y = np.append([np.sin(xShell)], [py[0:int(nmax)-1]]) ch1y = np.append([np.cos(xShell)], [chy[0:int(nmax)-1]]) gsy = py-(0+1.0j)*chy gs1y = p1y-(0+1.0j)*ch1y # B&H Equation 4.89 Dnu = np.zeros((int(nmx)),dtype=complex) Dnv = np.zeros((int(nmx)),dtype=complex) Dnw = np.zeros((int(nmx)),dtype=complex) for i in range(int(nmx)-1,1,-1): Dnu[i-1] = i/u-1/(Dnu[i]+i/u) Dnv[i-1] = i/v-1/(Dnv[i]+i/v) Dnw[i-1] = i/w-1/(Dnw[i]+i/w) Du = Dnu[1:int(nmax)+1] Dv = Dnv[1:int(nmax)+1] Dw = Dnw[1:int(nmax)+1] uu = m*Du-Dv vv = Du/m-Dv fv = pv/chv dns = ((uu*fv/pw)/(uu*(pw-chw*fv)+(pw/pv)/chv))+Dw gns = ((vv*fv/pw)/(vv*(pw-chw*fv)+(pw/pv)/chv))+Dw a1 = dns/mShell+n/xShell b1 = mShell*gns+n/xShell an = (py*a1-p1y)/(gsy*a1-gs1y) bn = (py*b1-p1y)/(gsy*b1-gs1y) return an, bn
def AxialEigenfunction(r, ri, m, mu): """Axial flow eigenfunction r --> radial location to evaluate eigenfunction at ri --> inner radius of axial jet engine m --> circumfrential acoustic mode mu --> eigenvalue (dependent on radial mode n) """ X = mu * ri return ( jv(m, mu * r) - (0.5 * (jv(m-1, X) - jv(m+1, X))) / (0.5 * (yv(m-1, X) - yv(m+1, X))) * yv(m, mu * r) )
def coefsb1_dgfet(k, tSi, tOX, epsOX, epsS): """ coefficient E in Eq.(14) of Ref.[1] """ k1 = k * radius k2 = k * (radius + tOX) A = jv(0, k1) / ((jv(0, k1) * yv(0, k2) - jv(0, k2) * yv(0, k1))) B = jv(1, k1) / (jv(1, k1) * yv(0, k2) - jv(0, k2) * yv(1, k1)) C = (1 - epsOX / epsS) * jv(0, k1)**2 + (1 - epsS / epsOX) * jv(1, k1)**2 E = math.pi**2 * jv(0, k1) * epsOX / (2 * math.log(1 + tOX / radius) * epsS * (A * B + (math.pi / 2 * k1)**2 * C)) return E
def sphericalHankel_deriv(n, z): if n == 0: Hankel_n = (np.sqrt((np.pi) / (2 * z ))) * ss.jv(n+1/2, z)+\ 1j * (np.sqrt ( np.pi / (2 * z ))) * ss.yv(n + 1 / 2, z) Hankel_nplus1 = (np.sqrt(np.pi / ( 2 * z))) * ss.jv(n + 3 / 2, z) +\ 1j * (np.sqrt ( np.pi / (2 * z ))) * ss.yv(n + 3 / 2,z) return ((n / z) * Hankel_n - Hankel_nplus1) elif n > 0: Hankel_n = (np.sqrt(np.pi / (2 * n))) * ss.jv(n + 1 / 2, z)+ \ 1j * (np.sqrt(np.pi / ( 2 * z))) * ss.yv(n + 1 / 2 , z) Hankel_ntake1 = (np.sqrt( np.pi / (2 * z))) * ss.jv(n - 1 / 2,z) +\ 1j * (np.sqrt(np.pi / (2 * z))) * ss.yv(n - 1 / 2, z) return (Hankel_ntake1 - ((n + 1) / z) * Hankel_n)
def AxialEigenvalFunc(x, m, ri, ro): """Determinant of axial flow boundary condition eigenfunctions, which is equal to zero. Use scipy solver to get eigenvalues x --> dependent variable (eigenvalue mu in axial flow eigenfunction) m --> Order of bessel function ri --> inner radius of jet engine ro --> ourter radius of jet engine """ X = x * ro Y = x * ri return ( 0.5 * (jv(m-1, X) - jv(m+1, X)) * 0.5 * (yv(m-1, Y) - yv(m+1, Y)) - 0.5 * (jv(m-1, Y) - jv(m+1, Y)) * 0.5 * (yv(m-1, X) - yv(m+1, X)) )
def plot_fig1(): plt.close('all') X = np.linspace(0, 10, 100) fig = plt.figure() ax1 = fig.add_subplot(121) ax1.set_xlabel('X') ax1.set_ylabel('J$_m$(x)') for m in range(5): ax1.plot(X, ss.jv(m, X), label="m = %s" % m) ax1.legend() ax1.set_xlim(0, np.max(X)) ax2 = fig.add_subplot(122) ax2.set_xlabel('X') ax2.set_ylabel('N$_m$(x)') for m in range(5): ax2.plot(X, ss.yv(m, X), label="m = %s" % m) ax2.legend() ax2.set_xlim([0, np.max(X)]) ax2.set_ylim([-1, .7]) plt.tight_layout() fig.savefig(parent + "Jm_Ym.png") plt.close() print("plot saved to /T13_BesselFunctions/Jm_Ym.png")
def Mie_abcd(m, x, nmax): """based on the MATLAB code by C. Maetzler, 2002 Ref.: (Maetzler 2002) """ n = arange(1,(nmax+1))*1.0 nu = n+0.5 z = m*x m2 = m*m sqx = sqrt(0.5 * pi / x) sqz = sqrt(0.5 * pi / z) bx = special.jv(nu, x) * sqx bz = special.jv(nu, z) * sqz yx = special.yv(nu, x) * sqx hx = (complex(1,0)*bx + complex(0,1)*yx) b1x = concatenate((array([(sin(x)/x)]),bx[0:(nmax-1)])) b1z = concatenate((array([(sin(z)/z)]),bz[0:(nmax-1)])) y1x = concatenate((array([(-cos(x)/x)]),yx[0:(nmax-1)])) h1x = complex(1,0)*b1x + complex(0,1)*y1x ax = x*b1x - n*bx az = z*b1z - n*bz ahx = x*h1x - n*hx an = (m2*bz*ax - bx*az)/(m2*bz*ahx - hx*az) bn = (bz*ax - bx*az)/(bz*ahx - hx*az) cn = (bx*ahx - hx*ax)/(bz*ahx - hx*az) dn = m*(bx*ahx - hx*ax)/(m2*bz*ahx - hx*az) return (an,bn,cn,dn)
def mie_abcd(self, m, x): nmax = round(2 + x + (4 * x**(1. / 3.))) i = 1.0j n = np.arange(1, nmax + 1, 1) nu = (n + 0.5) z = np.multiply(m, x) m2 = np.multiply(m, m) sqx = np.sqrt(0.5 * (math.pi) / x) sqz = np.sqrt(0.5 * (math.pi) / z) bx = (np.multiply((special.jv(nu, x)), sqx)) bz = np.multiply((special.jv(nu, z)), sqz) yx = np.multiply((special.yv(nu, x)), sqx) hx = bx + (i * yx) sinx = np.array((cmath.sin(x)) / x) b1x = np.append(sinx, bx[0:int(nmax - 1)]) sinz = (cmath.sin(z)) / z b1z = np.append(sinz, bz[0:int(nmax - 1)]) cosx = np.array((cmath.cos(x)) / x) y1x = np.append(-cosx, yx[0:int(nmax - 1)]) h1x = b1x + (i * y1x) ax = (np.multiply(x, b1x)) - (np.multiply(n, bx)) az = (np.multiply(z, b1z)) - (np.multiply(n, bz)) ahx = (np.multiply(x, h1x)) - (np.multiply(n, hx)) m2bz = np.multiply(m2, bz) antop = (np.multiply(m2bz, ax)) - np.multiply(bx, az) anbot = (m2 * bz * ahx) - (hx * az) an = np.true_divide(antop, anbot) bn = (bz * ax - bx * az) / (bz * ahx - hx * az) cn = (bx * ahx - hx * ax) / (bz * ahx - hx * az) dn = m * (bx * ahx - hx * ax) / (m2 * bz * ahx - hx * az) return np.array([an, bn, cn, dn])
def compute_eigenvector(r, sigma, m, zero): """ Return the eigenvector for the system. Args: r (np.array(float)): array of radial locations. sigma (float): ratio of inner to outer radius, ri/ro. m (int): circumferential wavenumber. zero (float): a zero of the determinant of the convected wave equation Returns: the eigenvector associated with the input 'm' and 'zero', evaluated at radial locations defined by the input array 'r'. Length of the return array is len(r). """ Q_mn = -sp.jvp(m, sigma * zero) / sp.yvp(m, sigma * zero) eigenvector = np.zeros(len(r)) for irad in range(len(r)): eigenvector[irad] = \ sp.jv(m, zero*r[irad]) + Q_mn*sp.yv(m, zero*r[irad]) # Normalize the eigenmode. Find abs of maximum value. ev_mag = np.absolute(eigenvector) ev_max = np.max(ev_mag) eigenvector = eigenvector / ev_max return eigenvector
def Mie_ab(m, x, n_max): # http://pymiescatt.readthedocs.io/en/latest/forward.html#Mie_ab mx = m * x nmax = np.round(2 + x + 4 * (x**(1 / 3))) nmx = np.round(max(nmax, np.abs(mx)) + 16) n = np.arange(1, nmax + 1) nu = n + 0.5 sx = np.sqrt(0.5 * np.pi * x) px = sx * jv(nu, x) p1x = np.append(np.sin(x), px[0:int(nmax) - 1]) chx = -sx * yv(nu, x) ch1x = np.append(np.cos(x), chx[0:int(nmax) - 1]) gsx = px - (0 + 1j) * chx gs1x = p1x - (0 + 1j) * ch1x # B&H Equation 4.89 Dn = np.zeros(int(nmx), dtype=complex) for i in range(int(nmx) - 1, 1, -1): Dn[i - 1] = (i / mx) - (1 / (Dn[i] + i / mx)) D = Dn[1:int(nmax) + 1] # Dn(mx), drop terms beyond nMax da = D / m + n / x db = m * D + n / x an = (da * px - p1x) / (da * gsx - gs1x) bn = (db * px - p1x) / (db * gsx - gs1x) return an, bn
def mie_abcd(m: complex, x: float) -> np.ndarray: nmax = np.int(np.round(2 + x + 4 * x**(1 / 3))) n = np.arange(1, nmax + 1).astype(int) nu = n + 0.5 z = m * x m2 = m * m sqx = np.sqrt(0.5 * np.pi / x) sqz = np.sqrt(0.5 * np.pi / z) bx = jv(nu, x) * sqx bz = jv(nu, z) * sqz yx = yv(nu, x) * sqx hx = bx + yx * 1j b1x = np.append(np.sin(x) / x, bx[0:nmax - 1]) b1z = np.append(np.sin(z) / z, bz[0:nmax - 1]) y1x = np.append(-np.cos(x) / x, yx[0:nmax - 1]) h1x = b1x + y1x * 1j ax = x * b1x - n * bx az = z * b1z - n * bz ahx = x * h1x - n * hx an = (m2 * bz * ax - bx * az) / (m2 * bz * ahx - hx * az) bn = (bz * ax - bx * az) / (bz * ahx - hx * az) cn = (bx * ahx - hx * ax) / (bz * ahx - hx * az) dn = m * (bx * ahx - hx * ax) / (m2 * bz * ahx - hx * az) return np.array([an, bn, cn, dn])
def bessel_function_2nd(x_input, order): """ This is a wrapper function around scipy's bessel function of the second kind, given any real order value. This wrapper also includes input verification. Input: x_input = The x value input of the bessel function. order = The value(s) of orders wanting to be computed. center = The x displacement from center (i.e. the new center) height = The y displacement from center (i.e. the new height offset) Output: y_output = The y value(s) from the bessel function. """ # Type check. x_input = valid.validate_float_array(x_input) if isinstance(order, (float, int)): order = valid.validate_float_value(order) else: order = valid.validate_float_array(order, deep_validate=True) # Compute the value(s) of the bessel_function y_output = sp_spcl.yv(order, x_input) return np.array(y_output, dtype=float)
def g1(z): ''' Function G1 (Fromme and Golberg, 1980) ''' z = z + 0. * 1j return -0.5 * np.pi * yv(1, z) - 1. / z + np.log(0.5 * z) * jv(1, z)
def Mie_ab(m,x): # http://pymiescatt.readthedocs.io/en/latest/forward.html#Mie_ab mx = m*x nmax = np.round(2+x+4*(x**(1/3))) nmx = np.round(max(nmax,np.abs(mx))+16) n = np.arange(1,nmax+1) nu = n + 0.5 sx = np.sqrt(0.5*np.pi*x) px = sx*jv(nu,x) p1x = np.append(np.sin(x), px[0:int(nmax)-1]) chx = -sx*yv(nu,x) ch1x = np.append(np.cos(x), chx[0:int(nmax)-1]) gsx = px-(0+1j)*chx gs1x = p1x-(0+1j)*ch1x # B&H Equation 4.89 Dn = np.zeros(int(nmx),dtype=complex) for i in range(int(nmx)-1,1,-1): Dn[i-1] = (i/mx)-(1/(Dn[i]+i/mx)) D = Dn[1:int(nmax)+1] # Dn(mx), drop terms beyond nMax da = D/m+n/x db = m*D+n/x an = (da*px-p1x)/(da*gsx-gs1x) bn = (db*px-p1x)/(db*gsx-gs1x) return an, bn
def weights(self,nu,zeroArr): """ return the weights for quadrature w_{ mu k} = Y_mu( pi xi_{nu k}/J_nu+1(Pi xi_{nu k}) """ piXi = M.pi*zeroArr return SS.yv(nu,piXi)/SS.jv(nu+1,piXi)
def nu_L(L, v): #return sp.riccati_jn(L,v) nu_list = [] for l in range(1, L + 1): nu_list.append(v * np.sqrt(np.pi / (2 * v)) * (sp.jv(l + 0.5, v) + 1j * sp.yv(l + 0.5, v))) return np.array(nu_list)
def sphhankel(self, order, x, mode): #general form of calculating spherical hankel functions of the first kind at x if np.isscalar(x): return np.sqrt(np.pi / (2*x)) * (sp.jv(order + 0.5 + mode, x) + 1j * sp.yv(order + 0.5 + mode, x)) # elif np.asarray(x).ndim == 1: ans = np.zeros((len(x), len(order)), dtype = np.complex128) for i in range(len(order)): ans[:,i] = np.sqrt(np.pi / (2*x)) * (sp.jv(i + 0.5 + mode, x) + 1j * sp.yv(i + 0.5 + mode, x)) return ans else: ans = np.zeros((x.shape + (len(order),)), dtype = np.complex128) for i in range(len(order)): ans[...,i] = np.sqrt(np.pi / (2*x)) * (sp.jv(i + 0.5 + mode, x) + 1j * sp.yv(i + 0.5 + mode, x)) return ans
def g0(z): ''' Function G0 (Fromme and Golberg, 1980) ''' z = z + 0. * 1j return 0.5 * np.pi * yv(0, z) - (np.euler_gamma + np.log(0.5 * z)) * jv( 0, z)
def bessel(): for i in range(1,360): x = i / 6.28 y1 = spl.jv(1,x) y2 = spl.yv(1,x) y3 = spl.jv(3,x) print("%7.3f, %7.3f, %7.3f, %7.3f" % (x, y1, y2, y3))
def sphneumm(self,order,vect): #calculates the spherical neumann function of order 'order' for the passed #vector import numpy from scipy.special import yv sphneumm=numpy.sqrt(numpy.pi/2./vect)*yv(order+0.5,vect) return sphneumm
def test_bessely_complex(self): def mpbessely(v, x): r = complex(mpmath.bessely(v, x, **HYPERKW)) if abs(r) > 1e305: # overflowing to inf a bit earlier is OK r = np.inf * np.sign(r) return r assert_mpmath_equal(lambda v, z: sc.yv(v.real, z), _exception_to_nan(mpbessely), [Arg(), ComplexArg()], n=15000)
def ogata(self, f,h,N, nu): zeros=jn_zeros(nu,N) xi=zeros/np.pi Jp1=jv(nu+1,np.pi*xi) w=yv(nu, np.pi * xi) / Jp1 get_psi=lambda t: t*np.tanh(np.pi/2*np.sinh(t)) get_psip=lambda t:np.pi*t*(-np.tanh(np.pi*np.sinh(t)/2)**2 + 1)*np.cosh(t)/2 + np.tanh(np.pi*np.sinh(t)/2) knots=np.pi/h*get_psi(h*xi) Jnu=jv(nu,knots) psip=get_psip(h*xi) F=f(knots) psip[np.isnan(psip)]=1.0 return np.pi*np.sum(w*F*Jnu*psip)
def riccati_bessel(order, argument, kind=1, overflow_protection=True): if overflow_protection: if kind == 1: return np.sqrt(np.pi * argument / 2) * spc.jv( order + 1 / 2, argument) elif kind == 2: return (np.sqrt(np.pi * argument / 2) \ * (spc.jv(order + 1 / 2, argument) \ - 1j * spc.yv(order + 1 / 2, argument))) elif kind == 3: return np.sqrt(np.pi * argument / 2) * spc.yv( order + 1 / 2, argument) else: raise ValueError("Only kind=1 and kind=2 allowed.") if kind == 1: return argument * spherical_jn(order, argument) elif kind == 2: return argument * spherical_hankel2(order, argument) elif kind == 3: return argument * spherical_yn(order, argument) else: raise ValueError("Only kind=1 and kind=2 allowed.")
def bessely(l, x): """The Bessel polynomial of the second kind. Parameters ---------- l : int, float Polynomial order x : number, ndarray The point(s) the polynomial is evaluated at Returns ------- float, ndarray The polynomial evaluated at x """ return yv(l, x)
def mie_coeff(m, x, nmax): ''' calculate Mie coefficients a_n, b_n inputs: * m [complex] - index of refraction * x [] - size parameter, x = 2*pi*r*m_medium/lambda * nmax [] - number of terms in expansion outputs: * an [] - Mie coefficients * bn [] - Mie coefficients ''' #create n array n = np.arange(1, nmax + 1) nu = n + 0.5 y = m * x m2 = m * m #calculate Bessel function quantities bx = ss.jv(nu, x) * (0.5 * np.pi / x)**0.5 by = ss.jv(nu, y) * (0.5 * np.pi / y)**0.5 yx = ss.yv(nu, x) * (0.5 * np.pi / x)**0.5 # change inf evals to very very large number instead yx[np.isinf(yx)] = 1e100 hx = bx + 1j * yx b1x = np.zeros(nmax, dtype=complex) b1x[0] = np.sin(x) / x b1x[1:nmax] = bx[0:nmax - 1] b1y = np.zeros(nmax, dtype=complex) b1y[0] = np.sin(y) / y b1y[1:nmax] = by[0:nmax - 1] y1x = np.zeros(nmax, dtype=complex) y1x[0] = -np.cos(x) / x y1x[1:nmax] = yx[0:nmax - 1] h1x = b1x + 1j * y1x ax = x * b1x - n * bx ay = y * b1y - n * by ahx = x * h1x - n * hx #finally the coefficients themselves an = (m2 * by * ax - bx * ay) / (m2 * by * ahx - hx * ay) bn = (by * ax - bx * ay) / (by * ahx - hx * ay) return an, bn
def CylWaveField(X, Y, Z, amplitudes, freq, wnumber, wdepth, Bodiescoord, disregard, plane=0): """ unused TBD """ NumBodies = len2(Bodiescoord) Nm = (len2(amplitudes) / NumBodies - 1) / 2 mode = range(-Nm, Nm + 1) XX, YY = meshgrid(X, Y, indexing='ij', sparse=True) Phii = zeros((NumBodies, XX.shape[0], YY.shape[1]), dtype=complex) for i in range(NumBodies): Xi, Yi = Bodiescoord[i] ri = sqrt((XX - Xi)**2 + (YY - Yi)**2) thetai = arctan2(YY - Yi, XX - Xi) Phii[i][ri <= disregard] = NaN a = amplitudes[(2 * Nm + 1) * i:(2 * Nm + 1) * (i + 1)] for m in mode[Nm:]: Psii = jv(m, wnumber * ri) - 1j * yv(m, wnumber * ri) if plane == 1: Phii[i] += a[Nm + m] * real(Psii) * exp(1j * m * thetai) if m > 0: Phii[i] += a[Nm - m] * real( (-1)**m * Psii) * exp(1j * -m * thetai) else: Phii[i] += a[Nm + m] * Psii * exp(1j * m * thetai) if m > 0: Phii[i] += a[Nm - m] * (-1)**m * Psii * exp( 1j * -m * thetai) Phii *= 1j * g / freq if len2(Z) == 1: return cosh(wnumber * (Z + wdepth)) / cosh(wnumber * wdepth) * Phii else: "Velocity potential" return array([ cosh(wnumber * (z + wdepth)) / cosh(wnumber * wdepth) * Phii for z in Z ], dtype=complex)
def get_covmatrix(self): """ Red covariance matrix depends on (i,j) matrix tau=abs(ToA_i - ToA_j) """ tau = np.abs(self.toa[:, np.newaxis] - self.toa) pow1 = .5 - self.params['alpha'] / 2 pow2 = -.5 - self.params['alpha'] / 2 pow3 = -.5 + self.params['alpha'] / 2 part1 = 2**pow1 / self.params['fc']**pow2 part2 = self.params['p0'] * spc.year**3 * np.sqrt(np.pi) part3 = (2 * np.pi * tau)**pow3 part4 = sps.yv(pow1, 2 * np.pi * tau * self.params['fc']) / sps.gamma( self.params['alpha'] / 2) np.fill_diagonal(part4, 0) # Replace inf by 0 self.cov_matrix = part1 * part2 * np.multiply(part3, part4) return self.cov_matrix
def __init__(self,xmin,xmax,nu): zero1 = jn_zeros(nu, 1)[0] h = fsolve(lambda h: xmin-zero1*np.tanh(np.pi/2*np.sinh(h/np.pi*zero1)), xmin)[0] k = fsolve(lambda k: xmax-np.pi*k*np.tanh(np.pi/2*np.sinh(h*k)), xmax)[0] N = int(k) #print #print '\nogata N=',N #sys.exit() zeros=jn_zeros(nu,N) xi=zeros/np.pi Jp1=jv(nu+1,np.pi*xi) self.w=yv(nu, np.pi * xi) / Jp1 get_psi=lambda t: t*np.tanh(np.pi/2*np.sinh(t)) get_psip=lambda t:np.pi*t*(-np.tanh(np.pi*np.sinh(t)/2)**2 + 1)*np.cosh(t)/2 + np.tanh(np.pi*np.sinh(t)/2) self.knots=np.pi/h*get_psi(h*xi) self.Jnu=jv(nu,self.knots) self.psip=get_psip(h*xi)
def dricbesy(l, x): """The first derivative of the Riccati-Bessel polynomial of the second kind. Parameters ---------- l : int, float Polynomial order x : number, ndarray The point(s) the polynomial is evaluated at Returns ------- float, ndarray The polynomial evaluated at x """ return -0.5 * np.sqrt(np.pi / 2 / x) * yv(l + 0.5, x) - np.sqrt( np.pi * x / 2) * dbessely(l + 0.5, x)
def jquad(func, v=0, h=1.e-3, N=200, **kwargs): ''' Numerically evaluate integrals of the following form /+inf I = | f(x).*besselj(v,x)dx /0 Parameters ---------- func : function handle Function to integrate, f(x). v : int Bessel function order. h : float Step size. N : int Number of nodes. Returns ------- I : float Approximation of integral. Notes ----- Based on Ogata's method, [1] H. Ogata, A Numerical Integration Formula Based on the Bessel Functions, Publications of the Research Institute for Mathematical Sciences, vol. 41, no. 4, pp. 949970, 2005. Python reimplementation of MATLAB code by AmirNader Askarpour (2011). Original source at https://www.mathworks.com/matlabcentral/fileexchange/33929-quadrature-rule-for-evaluating-integrals-containing-bessel-functions ''' # calculating zeros of Bessel function xi_vk = jn_zeros(v, N) / np.pi # weights w_vk = yv(v, np.pi * xi_vk) / jv(v + 1, np.pi * xi_vk) # quadrature S = np.pi * w_vk * func(np.pi / h * psi(h * xi_vk), **kwargs) * jv( v, np.pi / h * psi(h * xi_vk)) * d_psi(h * xi_vk) return np.sum(S)
def single_mie_coeff(eps,mu,x): """Mie coefficients for the single-layered sphere. Args: eps: The complex relative permittivity. mu: The complex relative permeability. x: The size parameter. Returns: A tuple containing (an, bn, nmax) where an and bn are the Mie coefficients and nmax is the maximum number of coefficients. """ z = sqrt(eps*mu)*x m = sqrt(eps/mu) nmax = int(round(2+x+4*x**(1.0/3.0))) nmax1 = nmax-1 nmx = int(round(max(nmax,abs(z))+16)) n = arange(nmax) nu = n+1.5 sx = sqrt(0.5*pi*x) px = sx*jv(nu,x) p1x = hstack((sin(x), px[:nmax1])) chx = -sx*yv(nu,x) ch1x = hstack((cos(x), chx[:nmax1])) gsx = px-complex(0,1)*chx gs1x = p1x-complex(0,1)*ch1x dnx = zeros(nmx,dtype=complex) for j in range(nmx-1,0,-1): r = (j+1.0)/z dnx[j-1] = r - 1.0/(dnx[j]+r) dn = dnx[:nmax] n1 = n+1 da = dn/m + n1/x db = dn*m + n1/x an = (da*px-p1x)/(da*gsx-gs1x) bn = (db*px-p1x)/(db*gsx-gs1x) return (an, bn, nmax)
def single_mie_coeff(eps, mu, x): """Mie coefficients for the single-layered sphere. Args: eps: The complex relative permittivity. mu: The complex relative permeability. x: The size parameter. Returns: A tuple containing (an, bn, nmax) where an and bn are the Mie coefficients and nmax is the maximum number of coefficients. """ z = sqrt(eps * mu) * x m = sqrt(eps / mu) nmax = int(round(2 + x + 4 * x**(1.0 / 3.0))) nmax1 = nmax - 1 nmx = int(round(max(nmax, abs(z)) + 16)) n = arange(nmax) nu = n + 1.5 sx = sqrt(0.5 * pi * x) px = sx * jv(nu, x) p1x = hstack((sin(x), px[:nmax1])) chx = -sx * yv(nu, x) ch1x = hstack((cos(x), chx[:nmax1])) gsx = px - complex(0, 1) * chx gs1x = p1x - complex(0, 1) * ch1x dnx = zeros(nmx, dtype=complex) for j in xrange(nmx - 1, 0, -1): r = (j + 1.0) / z dnx[j - 1] = r - 1.0 / (dnx[j] + r) dn = dnx[:nmax] n1 = n + 1 da = dn / m + n1 / x db = dn * m + n1 / x an = (da * px - p1x) / (da * gsx - gs1x) bn = (db * px - p1x) / (db * gsx - gs1x) return (an, bn, nmax)
def Mie_cd(m,x): # http://pymiescatt.readthedocs.io/en/latest/forward.html#Mie_cd mx = m*x nmax = np.round(2+x+4*(x**(1/3))) nmx = np.round(max(nmax,np.abs(mx))+16) n = np.arange(1,int(nmax)+1) nu = n+0.5 cnx = np.zeros(int(nmx),dtype=complex) for j in np.arange(nmx,1,-1): cnx[int(j)-2] = j-mx*mx/(cnx[int(j)-1]+j) cnn = np.array([cnx[b] for b in range(0,len(n))]) jnx = np.sqrt(np.pi/(2*x))*jv(nu, x) jnmx = np.sqrt((2*mx)/np.pi)/jv(nu, mx) yx = np.sqrt(np.pi/(2*x))*yv(nu, x) hx = jnx+(1.0j)*yx b1x = np.append(np.sin(x)/x, jnx[0:int(nmax)-1]) y1x = np.append(-np.cos(x)/x, yx[0:int(nmax)-1]) hn1x = b1x+(1.0j)*y1x ax = x*b1x-n*jnx ahx = x*hn1x-n*hx numerator = jnx*ahx-hx*ax c_denominator = ahx-hx*cnn d_denominator = m*m*ahx-hx*cnn cn = jnmx*numerator/c_denominator dn = jnmx*m*numerator/d_denominator return cn, dn
ea1 = N.array(0.0,dtype='complex') ea1 = EM_parameters.eps_r_by_subdomain[1]*eps_0 + 1j*EM_parameters.sigma_by_subdomain[1]/EM_parameters.om ea2 = N.array(0.0,dtype='complex') ea2 = EM_parameters.eps_r_by_subdomain[2]*eps_0 + 1j*EM_parameters.sigma_by_subdomain[2]/EM_parameters.om k1 = EM_parameters.om*N.sqrt(mu_0*ea1) k2 = EM_parameters.om*N.sqrt(mu_0*ea2) a = 0.12 R = 0.25 # construct system of equations A = N.matrix(N.zeros([3,3],dtype='complex')) b = N.matrix(N.zeros([3,1],dtype='complex')) A[0,0] = -special.jv(0,k1*a) A[0,1] = special.jv(0,k2*a) A[0,2] = special.yv(0,k2*a) A[1,0] = -k1*special.jv(1,k1*a) A[1,1] = k2*special.jv(1,k2*a) A[1,2] = k2*special.yv(1,k2*a) A[2,0] = 0.0 A[2,1] = special.jv(0,k2*R) A[2,2] = special.yv(0,k2*R) b[0] = 0.0 b[1] = 0.0 b[2] = 1.0 # solve system soln = N.linalg.solve(A,b)
def _weight(self): return yv(self._nu, np.pi * self._zeros) / self._j1(np.pi * self._zeros)
def spneumann(n, kr): """Spherical Neumann (Bessel second kind) of order n""" # spb2 = scy.sph_yn(n, kr) # return spb2[0][-1] return _np.sqrt(_np.pi / (2 * kr)) * scy.yv(n + 0.5, kr)
def coated_mie_coeff(eps1,eps2,x,y): """Mie coefficients for the dual-layered (coated) sphere. Args: eps: The complex relative permittivity of the core. eps2: The complex relative permittivity of the shell. x: The size parameter of the core. y: The size parameter of the shell. Returns: A tuple containing (an, bn, nmax) where an and bn are the Mie coefficients and nmax is the maximum number of coefficients. """ m1 = sqrt(eps1) m2 = sqrt(eps2) m = m2/m1 u = m1*x v = m2*x w = m2*y nmax = int(round(2+y+4*y**(1.0/3.0))) mx = max(abs(m1*y),abs(w)) nmx = int(round(max(nmax,mx)+16)) nmax1 = nmax-1 n = arange(nmax) dnu = zeros(nmax,dtype=complex) dnv = zeros(nmax,dtype=complex) dnw = zeros(nmax,dtype=complex) dnx = zeros(nmx,dtype=complex) for (z, dn) in zip((u,v,w),(dnu,dnv,dnw)): for j in range(nmx-1,0,-1): r = (j+1.0)/z dnx[j-1] = r - 1.0/(dnx[j]+r) dn[:] = dnx[:nmax] nu = n+1.5 vwy = [v,w,y] sx = [sqrt(0.5*pi*xx) for xx in vwy] (pv,pw,py) = [s*jv(nu,xx) for (s,xx) in zip(sx,vwy)] (chv,chw,chy) = [-s*yv(nu,xx) for (s,xx) in zip(sx,vwy)] p1y = hstack((sin(y), py[:nmax1])) ch1y = hstack((cos(y), chy[:nmax1])) gsy = py-complex(0,1)*chy gs1y = p1y-complex(0,1)*ch1y uu = m*dnu-dnv vv = dnu/m-dnv fv = pv/chv fw = pw/chw ku1 = uu*fv/pw kv1 = vv*fv/pw pt = pw-chw*fv prat = pw/pv/chv ku2 = uu*pt+prat kv2 = vv*pt+prat dns1 = ku1/ku2 gns1 = kv1/kv2 dns = dns1+dnw gns = gns1+dnw nrat = (n+1)/y a1 = dns/m2+nrat b1 = m2*gns+nrat an = (py*a1-p1y)/(gsy*a1-gs1y) bn = (py*b1-p1y)/(gsy*b1-gs1y) return (an, bn, nmax)
def mie_N4grid(field, kk, R, C, ce, ci, jumpe, jumpi, N, point): """ Requires: kk : numpy.array([kx, ky, kz]) R : radius of the sphere C : center of the sphere ce, ci : contrast sqrt(epsExt), sqrt*espInt) jumpe: coeff jump exterior (alpha_Dir, beta_Neu) jumpi: coeff jump interior (alpha_Dir, beta_Neu) N : Number of modes """ pt = point[:] kk = Cartesian(kk) k = kk.norm() kk = kk.normalized() # be careful with this test !! if sp.linalg.norm(sp.linalg.norm(pt - C) - R) > 0.3: return 0.0 + 0j else: p = Cartesian((pt[0], pt[1], pt[2])) pnorm = p.norm() pn = p.normalized() costheta = pn.dot(kk) kpnorm = k * pnorm ke, ki = ce * k, ci * k keR, kiR = ke * R, ki * R ae, be = jumpe ai, bi = jumpi ke_aeai = ke * ae * ai ki_aebi = ki * ae * bi ke_aibe = ke * ai * be ke_beae = ke * be * ae ke_bebe = ke * be * be ki_bebe = ke * ae * bi ke_aibe = ke * ai * be sqrt_e = sp.sqrt(sp.pi / (2 * keR)) sqrt_i = sp.sqrt(sp.pi / (2 * kiR)) sqrt_n = sp.sqrt(sp.pi / (2 * kpnorm)) sqrt_m = sp.sqrt(sp.pi / (2 * ci * kpnorm)) val = 0 for n in myrange(N): Je = sqrt_e * jv(n + 0.5, keR) Ji = sqrt_i * jv(n + 0.5, kiR) Jpe = (n / keR) * Je - sqrt_e * jv(n + 1.5, keR) Jpi = (n / kiR) * Ji - sqrt_i * jv(n + 1.5, kiR) Ye = sqrt_e * yv(n + 0.5, keR) Ype = (n / keR) * Ye - sqrt_e * yv(n + 1.5, keR) locH1 = Je + 1j * Ye locH1p = Jpe + 1j * Ype if field == "sca": a = ke_aeai * Ji * Jpe b = ki_aebi * Jpi * Je c = ki_aebi * locH1 * Jpi d = ke_aibe * locH1p * Ji v = (2 * n + 1) * ((1j) ** n) * (a - b) / (c - d) Jn = sqrt_n * jv(n + 0.5, kpnorm) Jpn = (n / kpnorm) * Jn - sqrt_n * jv(n + 1.5, kpnorm) Yn = sqrt_n * yv(n + 0.5, kpnorm) Ypn = (n / kpnorm) * Yn - sqrt_n * yv(n + 1.5, kpnorm) locH1p = Jpn + 1j * Ypn cn = k * v * locH1p elif field == "int": a = ke_beae * locH1 * Jpe b = ke_bebe * Je * locH1p c = ki_aebi * locH1 * Jpi d = ke_aibe * locH1p * Ji v = (2 * n + 1) * ((1j) ** n) * (a - b) / (c - d) Jn = sqrt_m * jv(n + 0.5, ci * kpnorm) Jpn = (n / (ci * kpnorm)) * Jn - sqrt_m * jv(n + 1.5, ci * kpnorm) cn = ci * k * v * Jpn else: cn = k * ((1j) ** n) * (2 * n + 1) * Jp(n, k * pnorm) c = eval_legendre(n, costheta) val += cn * c return val
def h(eta, k, w, Cj=1, Cy=0): n = 2./(1.+3.*w) p = n - 1./2. return eta**(-p) * (Cj*jv(p, k*eta) + Cy*yv(p, k*eta))
def test_bessely_complex(self): assert_mpmath_equal(lambda v, z: sc.yv(v.real, z), lambda v, z: _exception_to_nan(mpmath.bessely)(v, z, **HYPERKW), [Arg(), ComplexArg()], n=2000)
def yl(l, x): return numpy.sqrt(0.5 * numpy.pi / x) * yv(l + 0.5, x)
def eval(self,values,x): if x[0] < a: values[0] = N.abs(soln[0]*special.jv(0,k1*x[0])) else: values[0] = N.abs(soln[1]*special.jv(0,k2*x[0]) + soln[2]*special.yv(0,k2*x[0]))