def det_M1(η, m): c = η + 1 / η return lambda z: ( sp.ivp(m, η * z, 2) * sp.hankel1(m, z) + c * sp.ivp(m, η * z) * sp.h1vp(m, z) + sp.iv(m, η * z) * sp.h1vp(m, z, 2) )
def getResonantRadii(wl,rads,n,no=1,pol='TE',jmax=4,mmax=4): #Wave properties f = c / wl #Frequency (Hz) w = 2*pi*f #Angular Frequency (rad/s) d = 2*rads ko = 2*pi / wl #Wavevector (m^-1) # Return array of resonant radii Rs = zeros((jmax,mmax),dtype=float) * nan # iterate over mode order j for j in range(jmax): if pol == 'TE': dispersion = lambda x: no/n * jvp(j,n*x*ko) / jn(j,n*x*ko) - h1vp(j,x*ko*no) / h1n(j,x*ko*no) if pol == 'TM': dispersion = lambda x: n/no * jvp(j,n*x*ko) / jn(j,n*x*ko) - h1vp(j,x*ko*no) / h1n(j,x*ko*no) Fj = [dispersion(x) for x in rads] # All zero crossings are conveniently positive-negative with increasing radius. There are neg-pos discontinuities which must be avoided. # Find sign changes: xing = diff(sign(Fj)) #plot(rads[1:],xing) # retrieve radii corresponding to negative sign changes resonances = rads[where(xing==-2)] #truncate to maximum # of radial mode order resonances = resonances[:mmax] Rs[j,:len(resonances)] = resonances return Rs
def rootsAnnSec(m, rMin, rMax, aMin, aMax): f0 = lambda k: ivp(m, η * k) * hankel1(m, k) / η + iv(m, η * k) * h1vp( m, k) f1 = (lambda k: ivp(m, η * k, 2) * hankel1(m, k) + c * ivp(m, η * k) * h1vp(m, k) + iv(m, η * k) * h1vp(m, k, 2)) A = AnnulusSector(center=0.0, radii=(rMin, rMax), phiRange=(aMin, aMax)) z = A.roots(f0, df=f1) return z.roots
def C_prime(wl): kr1 = krho1_wg(wl) kr = kr1 * rho_c Hn = sp.hankel1(n_mode, kr) Hnp = sp.h1vp(n_mode, kr) Hnpp = sp.h1vp(n_mode, kr, 2) C1 = -Hnpp * kz_wg(wl) * rho_c / (kr1**2 * Hn) C2 = Hnp * kz_wg(wl) * (Hn / kr1 + rho_c * Hnp) / (kr1 * Hn)**2 return (C1 + C2)
def sMatrixElementCoefficients(k, n1, n2, m): A = -n1 * hankel2(m, n2 * k) * jvp(m, n1 * k) + n2 * jn(m, n1 * k) * h2vp( m, n2 * k) B = n1 * hankel1(m, n2 * k) * jvp(m, n1 * k) - n2 * jn(m, n1 * k) * h1vp( m, n2 * k) Ap = -n1 * n1 * jvp(m, n1 * k, 2) * hankel2(m, n2 * k) + n2 * n2 * jn( m, n1 * k) * h2vp(m, n2 * k, 2) Bp = n1 * n1 * jvp(m, n1 * k, 2) * hankel1(m, n2 * k) - n2 * n2 * jn( m, n1 * k) * h1vp(m, n2 * k, 2) return A, B, Ap, Bp
def matA_tm(n, m1, m2, m3, x1, x2): return np.array( [[m1 * jv(n, m1 * x1), -m2 * jv(n, m2 * x1), m2 * h1v(n, m2 * x1), 0], [ m1**2 * jvp(n, m1 * x1), -m2**2 * jvp(n, m2 * x1), m2**2 * h1vp(n, m2 * x1), 0 ], [0, m2 * jv(n, m2 * x2), -m2 * h1v(n, m2 * x2), m3 * h1v(n, m3 * x2)], [ 0, m2**2 * jvp(n, m2 * x2), -m2**2 * h1vp(n, m2 * x2), m3**2 * h1vp(n, m3 * x2) ]])
def P11NN(wl): k1 = k1_wg(wl) k2 = k2_wg(wl) kr1 = krho1_wg(wl) kr2 = krho2_wg(wl) kr1rc = kr1 * rho_c kr2rc = kr2 * rho_c Jn1 = sp.jv(n_mode, kr1rc) Jn2 = sp.jv(n_mode, kr2rc) Jnp1 = sp.jvp(n_mode, kr1rc) Jnp2 = sp.jvp(n_mode, kr2rc) Hn1 = sp.hankel1(n_mode, kr1rc) Hnp1 = sp.h1vp(n_mode, kr1rc) F = F_(wl) kzwg = kz_wg(wl) P = (kzwg/kr2**2 - kzwg/kr1**2)**2 * epsilon_fiber - \ (Jnp2 / (kr2 * Jn2) - Hnp1 / (kr1 * Hn1)) *\ (Jnp2 * k2**2 / (Jn2 * kr2) - Jnp1 * k1**2 / (Jn1 * kr1)) * rho_c**2 #print('kr1rc=', kr1rc) #print('kr2rc=', kr2rc) #print('F * K^3 = ', F * KONSTANTA**3) #print('P / K = ', Jn1 / (F * Hn1) * P / KONSTANTA) return (Jn1 / (F * Hn1) * P)
def get_neumann_bc(self, n): '''TODO: docstring''' return sp.jvp( n, self.get_wavenumber() * self.get_cylinder_radius(), 1) / sp.h1vp( n, self.get_wavenumber() * self.get_cylinder_radius(), 1)
def Mcyl(self, field, order, rho, phi, component, freq_index): n = order # bessel functions if field == "inc": k = self.kR_host[freq_index] / self.radius z1 = k * rho J1 = special.jv(order, z1) JD1 = special.jvp(order, z1) m_r = -order * k * J1 * np.sin(order * phi) / z1 m_phi = -k * JD1 * np.cos(order * phi) elif field == "sc": k = self.kR_host[freq_index] / self.radius z1 = k * rho H1 = special.hankel1(order, z1) HD1 = special.h1vp(order, z1) m_r = -n * k * H1 * np.sin(order * phi) / z1 m_phi = -k * HD1 * np.cos(order * phi) #print m_r, m_phi elif field == "int": q = self.kR_cyl[freq_index] / self.radius z2 = q * rho J2 = special.jv(order, z2) JD2 = special.jvp(order, z2) m_r = -order * q * J2 * np.sin(order * phi) / z2 m_phi = -q * JD2 * np.cos(order * phi) if component in ['r', 'rho']: return m_r elif component in ['phi']: return m_phi else: return np.array([m_r, m_phi])
def coeff_w_m(η, m, k): M = np.array( [[sp.iv(m, η * k), -sp.hankel1(m, k)], [sp.ivp(m, η * k) / η, sp.h1vp(m, k)]] ) V = np.array([[sp.jv(m, k)], [-sp.jvp(m, k)]]) S = np.linalg.solve(M, V) return (S[0, 0], S[1, 0])
def effective_coated_order(self, filling, polarization, order): ''' Calculate effective medium parameters using the coated cylinder model ''' R = self.radius k = self.k_host mu_h = 1.0 R2 = R / np.sqrt(filling) # bessel functions J0 = special.jv(order, k * R2) H0 = special.hankel1(order, k * R2) JD0 = special.jvp(order, k * R2) HD0 = special.h1vp(order, k * R2) m = order #aa0 = self.coeff(1,polarization) if polarization in ['H', 'TE']: aa1 = self.coeff(m, 'TE') denom = JD0 + HD0 * aa1 + 0j numer = (J0 + H0 * aa1) + 0j sum_ = m * numer / denom term = self.host_eps / (k * R2) return term * sum_ + 0j else: aa1 = self.coeff(m, 'TM') denom = JD0 + HD0 * aa1 + 0j numer = (J0 + H0 * aa1) + 0j sum_ = numer / denom / m term = self.host_mu / (k * R2) return term * sum_ + 0j
def effective_coated_N0(self, filling, polarization): ''' Calculate effective medium parameters using the coated cylinder model ''' R = self.radius k = self.k_host mu_h = 1.0 R2 = R / np.sqrt(filling) # bessel functions J0 = special.jv(0, k * R2) H0 = special.hankel1(0, k * R2) JD0 = special.jvp(0, k * R2) HD0 = special.h1vp(0, k * R2) aa0 = self.coeff(0, polarization) if polarization in ['H', 'TE']: numer = JD0 + HD0 * aa0 + 0j denom = (J0 + H0 * aa0) + 0j term = -2. * mu_h / (k * R2) return term * numer / denom + 0j else: aa0 = self.coeff(0, polarization) numer = JD0 + HD0 * aa0 + 0j denom = (J0 + H0 * aa0) + 0j term = -2 * self.host_eps / (k * R2) return term * numer / denom + 0j
def em_sca_coef_my(self): """ calculates self.an and self.bn scattering coefficients a[k], b[k] correspond to order k+1 """ m = np.sqrt(self.eps_t) * np.sqrt( self.mu_t) / (np.sqrt(self.eps_m) * np.sqrt(self.mu_m)) x = self.k * self.a nmax = int(round(x + 4 * x**(1. / 3.) + 2.)) self.nmax = np.round(max(nmax, np.abs(m * x)) + 16) besx = np.zeros(self.nmax, dtype=np.complex) dbesx = np.zeros(self.nmax, dtype=np.complex) dbesx2 = np.zeros(self.nmax, dtype=np.complex) hanx = np.zeros(self.nmax, dtype=np.complex) dhanx = np.zeros(self.nmax, dtype=np.complex) besmx_e = np.zeros(self.nmax, dtype=np.complex) dbesmx_e = np.zeros(self.nmax, dtype=np.complex) besmx_m = np.zeros(self.nmax, dtype=np.complex) dbesmx_m = np.zeros(self.nmax, dtype=np.complex) sqx = np.sqrt(0.5 * pi / x) dsqx = -0.5 * np.sqrt(0.5 * pi / x**3) sqmx = np.sqrt(0.5 * pi / (m * x)) dsqmx = -0.5 * np.sqrt(0.5 * pi / (m * x)**3) for n in range(1, self.nmax + 1): besx[n - 1] = sp_spec.spherical_jn(n, x) dbesx[n - 1] = sp_spec.spherical_jn(n, x, True) hanx[n - 1] = sqx * sp_spec.hankel1(n + 0.5, x) # sph. hankel 1st kind dhanx[n - 1] = sqx * sp_spec.h1vp(n + 0.5, x) + dsqx * sp_spec.hankel1( n + 0.5, x) # d. sph. hankel 1st n1 = np.sqrt(n * (n + 1) * self.eps_t / self.eps_r + 0.25) - 0.5 besmx_e[n - 1] = sqmx * sp_spec.jv(n1 + 0.5, m * x) dbesmx_e[n - 1] = sqmx * sp_spec.jvp( n1 + 0.5, m * x) + dsqmx * sp_spec.jv(n1 + 0.5, m * x) n2 = np.sqrt(n * (n + 1) * self.mu_t / self.mu_r + 0.25) - 0.5 besmx_m[n - 1] = sqmx * sp_spec.jv(n2 + 0.5, m * x) dbesmx_m[n - 1] = sqmx * sp_spec.jvp( n2 + 0.5, m * x) + dsqmx * sp_spec.jv(n2 + 0.5, m * x) self.an = ((self.mu_m * m**2 * (besx + x * dbesx) * besmx_e - self.mu_t * besx * (besmx_e + m * x * dbesmx_e)) / (self.mu_m * m**2 * (hanx + x * dhanx) * besmx_e - self.mu_t * hanx * (besmx_e + m * x * dbesmx_e))) self.bn = ((self.mu_t * (besx + x * dbesx) * besmx_m - self.mu_m * besx * (besmx_m + m * x * dbesmx_m)) / (self.mu_t * (hanx + x * dhanx) * besmx_m - self.mu_m * hanx * (besmx_m + m * x * dbesmx_m)))
def dricbesh(l, x): """The first derivative of the Riccati-Bessel polynomial of the third 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 """ xi = 0.5 * np.sqrt(np.pi / 2 / x) * h1vp(l + 0.5, x, False) + np.sqrt( np.pi * x / 2) * h1vp(l + 0.5, x, True) return xi
def besselh_derivative(n, k, z): """ Derivative of besselh """ if k == 2: return special.h2vp(n,z) elif 0 == 1: return special.h1vp(n,z) else: raise TypeError("Only second or first kind.")
def calcInt(): plaTrue = ε > -1.0 if plaTrue: Int = open(f"eps_{ε}_int", "w") Pla = open(f"eps_{ε}_pla", "w") else: Int = open(f"eps_{ε}_int", "w") for m in range(65): print(f"m = {m}") f0 = lambda k: ivp(m, η * k) * hankel1(m, k) / η + iv(m, η * k) * h1vp( m, k) f1 = (lambda k: ivp(m, η * k, 2) * hankel1(m, k) + c * ivp(m, η * k) * h1vp(m, k) + iv(m, η * k) * h1vp(m, k, 2)) t = np.linspace(0.2, 65.0, num=1024) k = 1j * t rf = np.real(f0(k)) ind = np.where(rf[1:] * rf[:-1] < 0.0)[0] roots = np.zeros(np.shape(ind), dtype=complex) for a, i in enumerate(ind): C = Circle(center=1j * (t[i] + t[i + 1]) / 2.0, radius=(t[i + 1] - t[i])) z = C.roots(f0, df=f1) roots[a] = z.roots[0] if plaTrue: if m: writeFile(Int, m, roots[1:]) writeFile(Pla, m, roots[[0]]) else: writeFile(Int, m, roots) else: writeFile(Int, m, roots) if plaTrue: Int.close() Pla.close() else: Int.close()
def B(k, n, a, l, nm=1.33): ka = k * nm * a kna = k * n * a jka = jv(l, ka) djka = jv(l, ka, True) jkna = jv(l, kna) djkna = jv(l, kna, True) h = h1vp(l, ka, n=1) return (2 * l + 1) * 1j ** l \ * (jka * djkna * n - jkna * djka * nm) \ / (jkna * h * nm - h * djkna * n)
def effective_coated_N1(self, filling, polarization, orders=1): ''' Calculate effective medium parameters using the coated cylinder model ''' R = self.radius k = self.k_host mu_h = 1.0 R2 = R / np.sqrt(filling) #aa0 = self.coeff(1,polarization) sum_ = 0.0 + 0j if polarization in ['H', 'TE']: if orders < 1: orders = 1 for m in np.arange(1, orders + 1): # bessel functions J0 = special.jv(m, k * R2) H0 = special.hankel1(m, k * R2) JD0 = special.jvp(m, k * R2) HD0 = special.h1vp(m, k * R2) aa1 = self.coeff(m, 'TE') denom = JD0 + HD0 * aa1 + 0j numer = (J0 + H0 * aa1) + 0j sum_ = sum_ + m * numer / denom term = self.host_eps / (k * R2) return term * sum_ + 0j else: for m in np.arange(1, orders + 1): J0 = special.jv(m, k * R2) H0 = special.hankel1(m, k * R2) JD0 = special.jvp(m, k * R2) HD0 = special.h1vp(m, k * R2) aa1 = self.coeff(m, 'TM') denom = JD0 + HD0 * aa1 + 0j numer = (J0 + H0 * aa1) + 0j sum_ = sum_ + m * numer / denom term = self.host_mu / (k * R2) return term * sum_ + 0j
def linton_evans_coeffs(k, incAng, numCylinders, centres, radii, M): # Four-cylinder problem #if k<=20: # M=40 #elif 20<k<=40: # M=80 #elif 40<k<=60: # M=120 #elif 60<k<=120: # M=180 #elif k>120: # M=300 N = numCylinders origin = centres a = radii i = np.arange(0, N).reshape(-1, 1) j = np.arange(0, N).reshape(1, -1) R = np.sqrt((origin[j, 0] - origin[i, 0])**2 + (origin[j, 1] - origin[i, 1])**2) alpha = np.angle((origin[j, 0] - origin[i, 0]) + 1j * (origin[j, 1] - origin[i, 1])) q = np.repeat(np.arange(N), 2 * M + 1).reshape(-1, 1) # rows p = np.repeat(np.arange(N), 2 * M + 1).reshape(1, -1) # cols m = np.repeat([np.arange(-M, M + 1)], N, axis=0).reshape(-1, 1) # rows n = np.repeat([np.arange(-M, M + 1)], N, axis=0).reshape(1, -1) # cols # Right-hand vector Iq = np.exp( 1j * k * (origin[q, 0] * np.cos(incAng) + origin[q, 1] * np.sin(incAng))) exponential1 = np.exp(1j * m * (np.pi / 2 - incAng)) RHS = -Iq * exponential1 # Left-hand side matrix Znp = jvp(n, k * a[p]) / h1vp(n, k * a[p]) exponential2 = np.exp(1j * (n - m) * alpha[p, q]) Hnm = hankel1(n - m, k * R[p, q]) LHS = Znp * exponential2 * Hnm Identity = np.identity(2 * M + 1) for cyl in range(N): LHS[cyl * (2 * M + 1):(cyl + 1) * (2 * M + 1), cyl * (2 * M + 1):(cyl + 1) * (2 * M + 1)] = Identity # Solve for values of Anq A = np.linalg.solve(LHS, RHS) return A
def h1vp_cached(L, hin): hin_max = np.max(hin) if hin_max > CACHE["maxKR"]: calc_arr = np.arange(CACHE["maxKR"] + CACHE["resolution"], hin_max + CACHE["resolution"], CACHE["resolution"]) for l in range(CACHE["maxL"]): CACHE["L"][l] = np.concatenate((CACHE["L"][l], h1vp(l, calc_arr))) CACHE["maxKR"] = calc_arr[-1] if L > len(CACHE["L"]): calc_arr = np.arange(0, CACHE["maxKR"] + CACHE["resolution"], CACHE["resolution"]) for l in range(len(CACHE["L"]), L): CACHE["L"].append(h1vp(l, calc_arr)) CACHE["maxL"] = L residx = ((hin // CACHE["resolution"])).astype(np.int) c = CACHE["L"] out = [c[l][residx] for l in range(L)] return out
def coeff(self, order, polarization, freq_index=None, denominator=False): n = order # for backward compatibility # for backward compatibility only z1 = self.kR_host z2 = self.kR_cyl if freq_index >= 0: z1 = self.kR_host[freq_index] z2 = self.kR_cyl[freq_index] k0 = self.k0[freq_index] kR_cyl = self.kR_cyl[freq_index] kR_host = self.kR_host[freq_index] else: z1 = self.kR_host z2 = self.kR_cyl k0 = self.k0 kR_cyl = self.kR_cyl kR_host = self.kR_host # bessel functions J1 = special.jv(order, z1) J2 = special.jv(order, z2) JD1 = special.jvp(order, z1) JD2 = special.jvp(order, z2) H1 = special.hankel1(order, z1) HD1 = special.h1vp(order, z1) mu1 = self.host_mu mu2 = self.cyl_mu if polarization not in ['E', 'H', 'TE', 'TM']: raise ValueError("ERROR: Polarization should be 'E' or 'H'.") ### POLARIZATION if polarization in ['TE', 'H']: # scattering coefficienct bn (TE-pol) numer = kR_cyl * self.host_mu * J2 * JD1 - kR_host * self.cyl_mu * J1 * JD2 denom = kR_host * self.cyl_mu * H1 * JD2 - kR_cyl * self.host_mu * HD1 * J2 #print kR_cyl[0],self.host_mu,J2[0],JD1[0],kR_host[0],J1[0],JD2[0] if denominator: return denom return numer / denom elif polarization in ['TM', 'E']: # scattering coefficienct bn (TM-pol) numer = kR_cyl * self.host_mu * J1 * JD2 - kR_host * self.cyl_mu * J2 * JD1 denom = kR_host * self.cyl_mu * HD1 * J2 - kR_cyl * self.host_mu * H1 * JD2 if denominator: return denom return numer / denom
def coeff_func(self, p, frequency, order, filling, polarization): n = order # for backward compatibility # for backward compatibility only eps_eff, mu_eff = p ind = 1 if eps_eff.real < 0 and mu_eff.real < 0: ind = -1 n_eff = ind * np.sqrt(eps_eff * mu_eff) R2 = self.radius * np.sqrt(filling) denominator = False z1 = self.host_n * 2 * np.pi * frequency * R2 / constants.c z2 = n_eff * 2 * np.pi * frequency * R2 / constants.c freq_index = 0 #z2 = self.kR_cyl #k0 = self.k0 kR_cyl = z2 kR_host = z1 # bessel functions J1 = special.jv(order, z1) J2 = special.jv(order, z2) JD1 = special.jvp(order, z1) JD2 = special.jvp(order, z2) H1 = special.hankel1(order, z1) HD1 = special.h1vp(order, z1) mu1 = self.host_mu mu2 = mu_eff if polarization not in ['E', 'H', 'TE', 'TM']: raise ValueError("ERROR: Polarization should be 'E' or 'H'.") ### POLARIZATION if polarization in ['TE', 'H']: # scattering coefficienct bn (TE-pol) numer = kR_cyl * self.host_mu * J2 * JD1 - kR_host * self.cyl_mu * J1 * JD2 denom = kR_host * self.cyl_mu * H1 * JD2 - kR_cyl * self.host_mu * HD1 * J2 #print kR_cyl[0],self.host_mu,J2[0],JD1[0],kR_host[0],J1[0],JD2[0] if denominator: return denom return numer / denom elif polarization in ['TM', 'E']: # scattering coefficienct bn (TM-pol) numer = kR_cyl * self.host_mu * J1 * JD2 - kR_host * self.cyl_mu * J2 * JD1 denom = kR_host * self.cyl_mu * HD1 * J2 - kR_cyl * self.host_mu * H1 * JD2 if denominator: return denom aa = numer / denom return aa #(np.real(aa), np.imag(aa))
def te_moment(n, x, order): """ n: Complex refractive index. Array or scalar. x: Real size parameter of cylinder. Array or scalar. order: The order of the moment to return. """ # Calculating moment value for all wavelengths. # If refractive_index is a scalar, it will be the same for all wavelengths # If an array, must have same length as wavelength array. nx = n * x numer = n * jv(order, nx) * jvp(order, x) - jvp(order, nx) * jv(order, x) denom = n * jv(order, nx) * h1vp(order, x) - jvp(order, nx) * h1v(order, x) with np.errstate(divide='ignore', invalid='ignore'): return numer / denom
def ricbesh(l, x): """The Riccati-Bessel polynomial of the third 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 np.sqrt(np.pi * x / 2) * h1vp(l + 0.5, x, False)
def Bescoef(k,r,a,n): """ The calculates the Bessel and Hankel function coef for the incident and scattered wave solution. spec.jv(v,z) - Bessel Func of the first kind of order v spec.jvp(v,z) - first derivative of BF of the first kinda of order v spec.h1vp(v,z) - first derivative of Hankel Func of order v spec.hankel1(v,z) - Hankel func of the first kind of order v """ kr , ka = k*r , k*a coef = -(spec.jvp(n,ka,n=1)/spec.h1vp(n,ka,n=1))*spec.hankel1(n,kr) return coef
def linton_evans_coeffs(k,incAng,numCylinders,centres,radii,M): # Four-cylinder problem #if k<=20: # M=40 #elif 20<k<=40: # M=80 #elif 40<k<=60: # M=120 #elif 60<k<=120: # M=180 #elif k>120: # M=300 N = numCylinders origin = centres a = radii i = np.arange(0,N).reshape(-1,1) j = np.arange(0,N).reshape(1,-1) R = np.sqrt((origin[j,0]-origin[i,0])**2+(origin[j,1]-origin[i,1])**2) alpha = np.angle((origin[j,0]-origin[i,0]) +1j*(origin[j,1]-origin[i,1])) q = np.repeat(np.arange(N),2*M+1).reshape(-1,1) # rows p = np.repeat(np.arange(N),2*M+1).reshape(1,-1) # cols m = np.repeat([np.arange(-M,M+1)],N,axis=0).reshape(-1,1) # rows n = np.repeat([np.arange(-M,M+1)],N,axis=0).reshape(1,-1) # cols # Right-hand vector Iq = np.exp(1j*k*(origin[q,0]*np.cos(incAng)+origin[q,1]*np.sin(incAng))) exponential1 = np.exp(1j*m*(np.pi/2-incAng)) RHS = - Iq * exponential1 # Left-hand side matrix Znp = jvp(n,k*a[p]) / h1vp(n,k*a[p]) exponential2 = np.exp(1j*(n-m)*alpha[p,q]) Hnm = hankel1(n-m,k*R[p,q]) LHS = Znp * exponential2 * Hnm Identity = np.identity(2*M+1) for cyl in range(N): LHS[cyl*(2*M+1):(cyl+1)*(2*M+1),cyl*(2*M+1):(cyl+1)*(2*M+1)] = Identity # Solve for values of Anq A=np.linalg.solve(LHS,RHS) return A
def cylinder(wavenumber, xPlotPoints, yPlotPoints, radius=1.0): """ Analytical potential on hard cylinder with [1,0] incident wave (Jones)""" x = xPlotPoints y = yPlotPoints theta = np.arctan2(y, x) numPoints = len(x) nans = False, False N = 100 while any(nans) == False: N += 50 n = np.arange(0, N) neumann = 2 * np.ones(N) neumann[0] = 1 dJ = jvp(n, wavenumber * radius, 1) H1 = hankel1(n, wavenumber * radius) dH1 = h1vp(n, wavenumber * radius, 1) nans = np.isnan(dJ) + np.isnan(H1) + np.isnan(dH1) dJ = dJ.compress(np.logical_not(nans)) H1 = H1.compress(np.logical_not(nans)) dH1 = dH1.compress(np.logical_not(nans)) neumann = neumann.compress(np.logical_not(nans)) n = n.compress(np.logical_not(nans)) total = (-neumann * (1j**n) * dJ * H1 / dH1).reshape(-1, 1) cosines = np.cos(n.reshape(-1, 1) * theta) total = total * cosines incPotential = np.exp(1j * wavenumber * x).reshape(numPoints) fullPotential = np.sum(total, axis=0) + incPotential return fullPotential
def linton_evans_potential(k,Q,aq,thetaq,Acoeffs,M): ## Four-cylinder problem #if k<=20: # M=40 #elif 20<k<=40: # M=80 #elif 40<k<=60: # M=120 #elif 60<k<=120: # M=180 #elif k>120: # M=300 # Find potential at (aq,thetaq) Anq = Acoeffs[Q*(2*M+1):(Q+1)*(2*M+1)] n2 = np.arange(-M,M+1).reshape(-1,1) summation = np.sum( Anq / h1vp(n2,k*aq) * np.exp(1j*n2*thetaq) , axis=0) phi = -2j / (np.pi*k*aq) * summation return phi
def cylinder(wavenumber,xPlotPoints,yPlotPoints,radius=1.0): """ Analytical potential on hard cylinder with [1,0] incident wave (Jones)""" x = xPlotPoints y = yPlotPoints theta = np.arctan2(y,x) numPoints = len(x) nans=False,False N = 100 while any(nans)==False: N += 50 n = np.arange(0,N) neumann = 2*np.ones(N); neumann[0]=1 dJ = jvp(n,wavenumber*radius,1) H1 = hankel1(n,wavenumber*radius) dH1 = h1vp(n,wavenumber*radius,1) nans = np.isnan(dJ) + np.isnan(H1) + np.isnan(dH1) dJ = dJ.compress(np.logical_not(nans)) H1 = H1.compress(np.logical_not(nans)) dH1 = dH1.compress(np.logical_not(nans)) neumann = neumann.compress(np.logical_not(nans)) n = n.compress(np.logical_not(nans)) total = (-neumann * (1j**n) * dJ * H1 / dH1).reshape(-1,1) cosines = np.cos(n.reshape(-1,1)*theta) total = total * cosines incPotential = np.exp(1j*wavenumber*x).reshape(numPoints) fullPotential = np.sum(total,axis=0) + incPotential return fullPotential
def linton_evans_potential(k, Q, aq, thetaq, Acoeffs, M): ## Four-cylinder problem #if k<=20: # M=40 #elif 20<k<=40: # M=80 #elif 40<k<=60: # M=120 #elif 60<k<=120: # M=180 #elif k>120: # M=300 # Find potential at (aq,thetaq) Anq = Acoeffs[Q * (2 * M + 1):(Q + 1) * (2 * M + 1)] n2 = np.arange(-M, M + 1).reshape(-1, 1) summation = np.sum(Anq / h1vp(n2, k * aq) * np.exp(1j * n2 * thetaq), axis=0) phi = -2j / (np.pi * k * aq) * summation return phi
def coeff_int(self, order, polarization, freq_index=None): #if self.frequency == None: # raise Exception("ERROR: Frequency range has not been specified.") # for backward compatibility only mu1 = self.host_mu mu2 = self.cyl_mu if freq_index >= 0: z1 = self.kR_host[freq_index] z2 = self.kR_cyl[freq_index] k0 = self.k0[freq_index] kR_cyl = self.kR_cyl[freq_index] kR_host = self.kR_host[freq_index] else: z1 = self.kR_host z2 = self.kR_cyl k0 = self.k0 kR_cyl = self.kR_cyl kR_host = self.kR_host bn = self.coeff(order, polarization, freq_index) ### POLARIZATION if polarization in ['TE', 'H']: JD1 = special.jvp(order, z1) JD2 = special.jvp(order, z2) HD1 = special.h1vp(order, z1) numer = HD1 * bn + JD1 denom = JD2 return numer / denom elif polarization in ['TM', 'E']: J2 = special.jv(order, z2) J1 = special.jv(order, z1) H1 = special.hankel1(order, z1) numer = H1 * bn + J1 denom = J2 return numer / denom
def rfnd(self, n, x, d): return ss.h1vp(n,x,d)
import scipy as sp import scipy.special as spl import matplotlib.pyplot as plt #%% create axes x1 = 5 x = sp.linspace(0, x1, 5000) #Note for higher order Hankel functions exclude x values close to the origin n0 = 6 #Lower bound to generate n = 8 #Upper bound to generate a = 8.7 #Arbitrary constant corresponding to refractive index J = [spl.jv(n0, x)] #Bessel function, order n0; argument x H = [spl.hankel1(n0, x)] #Hankel function, order n0; argument x Ja = [spl.jv(n0, x*a)] #Bessel function, order n0; argument a*x Jdash = [spl.jvp(n0, x, n=1)] #Bessel function first derivative, order n0; argument x Hdash = [spl.h1vp(n0, x, n=1)] #Hankel function first derivative, order n0; argument x Jadash = [spl.jvp(n0, x*a, n=1)] #Bessel function first derivative, order 0; argument a*x for i in range(n0, n): J.append(spl.jv(i+1, x)) #Create Bessel functions, order n0+1-->n; argument x H.append(spl.hankel1(i+1, x)) #Create Hankel functions, order n0+1-->n; argument x Ja.append(spl.jv(i+1, x*a)) #Create Bessel functions, order n0+1-->n; argument a*x Jdash.append(spl.jvp(i+1, x, n=1)) #Create Bessel first derivatives, order n0+1-->n; argument x Hdash.append(spl.h1vp(i+1, x, n=1)) #Create Hankel first derivatives, order n0+1-->n; argument x Jadash.append(spl.jvp(i+1, x*a, n=1)) #Create Bessel first derivatives, order 1-->n; argument a*x eigroot = [Jadash[0]/Ja[0] - Hdash[0]/(a*H[0])] for i in range(0, n-n0): eigroot.append(Jadash[i+1]/Ja[i+1] - Hdash[i+1]/(a*H[i+1])) #%% plots plt.subplot(3, 1, 1) #Bessel functions plt.title("Bessel functions")
# Geometry R = 0.4 x = 0 y = 0 alpha = np.empty((mmax, countf), dtype=np.complex128) beta = np.empty((mmax, countf), dtype=np.complex128) for idx in range(countf): f = frequencies[idx] kv = 2 * np.pi * f k = math.sqrt(epsilon * mi) * kv for m in range(mmax): A = np.array( [ [ bessel.jv (m, k*R), -bessel.hankel1 (m, kv*R) / bessel.h1vp (m, kv*R) ],\ [ 1./zeta *bessel.jvp (m, k*R), -1 ]]) y = np.array([[bessel.jv(m, kv * R)], [bessel.jvp(m, kv * R)]]) if (np.linalg.det(A) != 0): x = np.linalg.solve(A, y) else: x = np.array([[0], [0]]) alpha[m, idx] = x[0, 0] beta[m, idx] = x[1, 0] np.savez("./Results/1cylinder1.npz", frequencies=frequencies, alpha=alpha, beta=beta, R=R,
def forceFO(k,A,h,cylR): rho = 999.97 g = 9.81 return (4*rho*g*A*np.tanh(k*h))/(k**2*spec.h1vp(1,k*cylR))
def sMatrixElementCoefficients(k,n1,n2,m): A = -n1*hankel2(m,n2*k)*jvp(m,n1*k)+n2*jn(m,n1*k)*h2vp(m,n2*k) B = n1*hankel1(m,n2*k)*jvp(m,n1*k)-n2*jn(m,n1*k)*h1vp(m,n2*k) Ap = -n1*n1*jvp(m,n1*k,2)*hankel2(m,n2*k)+n2*n2*jn(m,n1*k)*h2vp(m,n2*k,2) Bp = n1*n1*jvp(m,n1*k,2)*hankel1(m,n2*k)-n2*n2*jn(m,n1*k)*h1vp(m,n2*k,2) return A, B, Ap, Bp
def det_M0(η, m): return lambda z: ( sp.ivp(m, η * z) * sp.hankel1(m, z) / η + sp.iv(m, η * z) * sp.h1vp(m, z) )
if __name__ == '__main__': mesh = [25, 50, 100, 200, 300,500,1000,2000] convergence = np.zeros((0,2)) for nPoints in mesh: y = homoCircle(nPoints, 1.0, 2.0, 1.0, 1.0, 1) scatMat = y.computeScatteringMatrix(y.Mmax) analScatMat = np.zeros(2*y.Mmax+1, dtype=complex) zc = y.nc*y.k zo = y.no*y.k eta = y.nc/y.no for i in range(2*y.Mmax+1): m = i-y.Mmax num = -(eta*jvp(m,zc)*hankel2(m,zo)-jn(m,zc)*h2vp(m,zo)) den = eta*jvp(m,zc)*hankel1(m,zo)-jn(m,zc)*h1vp(m,zo) analScatMat[i] = num/den err = np.amax(np.abs(np.diag(analScatMat)-scatMat)) print(err) print(analScatMat) # -- Mean areas of triangles convergence = np.insert(convergence, len(convergence), [np.mean(y.areas), err],axis=0) fig1 = plt.figure(figsize=(5,3)) ax1 = fig1.add_subplot(111) plt.plot(convergence[:,0],convergence[:,1], ls='--', marker='o', label=r"Numerical Error") p = np.polyfit(np.log(convergence[:,0]),np.log(convergence[:,1]),1) ynew = np.exp(np.polyval(p,np.log(convergence[:,0]))) plt.plot(convergence[:,0],ynew, label=r"Power-law fit: $\alpha=%0.2g$" %(p[0]))