def solve(self, init, x): A = np.zeros((2, 2)) A[0][0] = special.sph_jn(self.l, self.function(x[0]))[0][self.l] A[0][1] = special.sph_yn(self.l, self.function(x[0]))[0][self.l] A[1][0] = self.function.deriv(1)(x[0]) * special.sph_jn( self.l, self.function(x[0]))[1][self.l] A[1][1] = self.function.deriv(1)(x[0]) * special.sph_yn( self.l, self.function(x[0]))[1][self.l] c = np.linalg.solve(A, init) y = np.zeros((len(x), 2)) for i in range(len(x)): for j in range(2): if j == 0: y[i][j] = \ c[0]*special.sph_jn(self.l,self.function(x[i]))[j][self.l] + \ c[1]*special.sph_yn(self.l,self.function(x[i]))[j][self.l] elif j == 1: y[i][j] = \ c[0]*self.function.deriv(1)(x[i])*special.sph_jn(self.l,self.function(x[i]))[j][self.l] + \ c[1]*self.function.deriv(1)(x[i])*special.sph_yn(self.l,self.function(x[i]))[j][self.l] self.x = x self.y = y return y
def __init__(self, k): self.k = k self.kExt = k l_max = 200 l = np.arange(0, l_max + 1) jExt, djExt = sph_jn(l_max, self.kExt) yExt, dyExt = sph_yn(l_max, self.kExt) hExt = jExt + 1j * yExt aInc = (2 * l + 1) * 1j**l np.seterr(divide='ignore', invalid='ignore') cBound = 1 / (1j * self.kExt) / hExt cDir = jExt / hExt for l in range(l_max + 1): if abs(cBound[l]) < 1e-16: # neglect all further terms l_max = l - 1 aInc = aInc[:l] cBound = cBound[:l] cDir = cDir[:l] break self.cDir = cDir self.aInc = aInc self.cBound = cBound self.l_max = l_max
def __init__(self, k): self.k = k kExt = k l_max = 200 l = np.arange(0, l_max + 1) jExt, djExt = sph_jn(l_max, kExt) yExt, dyExt = sph_yn(l_max, kExt) hExt = jExt + 1j * yExt aInc = (2 * l + 1) * 1j ** l np.seterr(divide='ignore', invalid='ignore') cBound = 1/(1j * kExt) / hExt cDir = jExt / hExt cBoundSq = (2l + 1) * 1j ** (l-2) / (hExt**2) / (kExt**2) / jExt for l in range(l_max + 1): if abs(cBound[l]) < 1e-16: # neglect all further terms l_max = l - 1 aInc = aInc[:l] cBound = cBound[:l] cBoundSq = cBoundSq[:l] cDir = cDir[:l] break self.cDir = cDir self.aInc = aInc self.cBound = cBound self.l_max = l_max self.cBoundSq = cBoundSq
def translator (r, s, phi, theta, l): ''' Compute the diagonal translator for a translation distance r, a translation direction s, azimuthal samples specified in the array phi, polar samples specified in the array theta, and a truncation point l. ''' # The radial argument kr = 2. * math.pi * r # Compute the radial component hl = spec.sph_jn(l, kr)[0] + 1j * spec.sph_yn(l, kr)[0] # Multiply the radial component by scale factors in the translator m = numpy.arange(l + 1) hl *= (1j / 4. / math.pi) * (1j)**m * (2. * m + 1.) # Compute Legendre angle argument dot(s,sd) for sample directions sd stheta = numpy.sin(theta)[:,numpy.newaxis] sds = (s[0] * stheta * numpy.cos(phi)[numpy.newaxis,:] + s[1] * stheta * numpy.sin(phi)[numpy.newaxis,:] + s[2] * numpy.cos(theta)[:,numpy.newaxis]) # Initialize the translator tr = 0 # Sum the terms of the translator for hv, pv in zip(hl, poly.legpoly(sds, l)): tr += hv * pv return tr
def uExactDirichletTrace(self, point): x, y, z = point r = np.sqrt(x**2 + y**2 + z**2) hD, dhD = sph_jn(self.l_max, self.kExt) + 1j * sph_yn(self.l_max, self.kExt * r) Y, dY = lpn(self.l_max, x / r) return (self.cDir * hD * Y).sum()
def uExactBoundaryDirichletTrace(self, point, normal, domain_index, result): x, y, z = point r = np.sqrt(x**2 + y**2 + z**2) hD, dhD = sph_jn(self.l_max, self.kExt) + 1j * sph_yn(self.l_max, self.kExt * r) Y, dY = lpn(self.l_max, x / r) result[0] = (self.cDir * hD * Y).sum()
def amplitude(wf, R, edash, mu): # Mies F ~ JA + NB J ~ sin(kR)/kR # normalization sqrt(2 mu/pu hbar^2) = zz zz = np.sqrt(2*mu/const.pi)/const.hbar oo, n, nopen = wf.shape # two asymptotic points on wavefunction wf[:, j] i1 = oo-5 i2 = i1-1 x1 = R[i1]*1.0e-10 x2 = R[i2]*1.0e-10 A = np.zeros((nopen, nopen)) B = np.zeros((nopen, nopen)) oc = 0 for j in range(n): if edash[j] < 0: continue # open channel ke = np.sqrt(2*mu*edash[j]*const.e)/const.hbar rtk = np.sqrt(ke) kex1 = ke*x1 kex2 = ke*x2 j1 = sph_jn(0, kex1)[0]*x1*rtk*zz y1 = sph_yn(0, kex1)[0]*x1*rtk*zz j2 = sph_jn(0, kex2)[0]*x2*rtk*zz y2 = sph_yn(0, kex2)[0]*x2*rtk*zz det = j1*y2 - j2*y1 for k in range(nopen): A[oc, k] = (y2*wf[i1, j, k] - y1*wf[i2, j, k])/det B[oc, k] = (j1*wf[i2, j, k] - j2*wf[i1, j, k])/det oc += 1 AI = linalg.inv(A) K = B @ AI return K, AI, B
def TotalField(x, alpha): global numTerms r = np.linalg.norm(x) h, hp = special.sph_yn(numTerms - 1, r) # arrays of Bessel 2nd kind and its derivatives theta, phi = thetaphi(x / r) YY = complexYMat(theta, phi) U = np.exp(1j * k * np.dot(alpha, x)) # return Total Field = Incident Field + Scattered Field return U + np.sum(h * np.sum(ScatteringCoeff(alpha) * YY, axis=1))
def SpherePlaneWave(k,x): """Find acoustic potential from planewave [1,0,0] scattered by sphere of radius 1. Potentials are solved for a points p = r*cos(x) and so r must be the same for all points.""" ka=k kr=k x=np.asarray(x,np.float).reshape(-1,) theta = np.arccos(x) N=0 badcells=False,False while any(badcells)==False: N += 100 n = np.arange(N+1) djnka = sph_jn(N,ka)[1] dynka = sph_yn(N,ka)[1] dhnka = djnka + 1j*dynka jnkr = sph_jn(N,kr)[0] ynkr = sph_yn(N,kr)[0] hnkr = jnkr + 1j*ynkr simplefilter("ignore") pscat= - (1j**n) * (2*n+1) * djnka * hnkr / dhnka simplefilter("default") badcells = np.isnan(pscat)+np.isinf(pscat) pscat = np.repeat([pscat],x.size,axis=0) * Pn(N,np.cos(theta)) pscat = pscat.compress(np.logical_not(badcells),axis=1) pinc = np.exp(1j*k*x) return np.sum(pscat,axis=1) + pinc
def test_mie_internal_coeffs(): m = 1.5 + 0.1j x = 50. n_stop = miescatlib.nstop(x) al, bl = miescatlib.scatcoeffs(m, x, n_stop) cl, dl = miescatlib.internal_coeffs(m, x, n_stop) jlx = sph_jn(n_stop, x)[0][1:] jlmx = sph_jn(n_stop, m * x)[0][1:] hlx = jlx + 1.j * sph_yn(n_stop, x)[0][1:] assert_allclose(cl, (jlx - hlx * bl) / jlmx, rtol=1e-6, atol=1e-6) assert_allclose(dl, (jlx - hlx * al) / (m * jlmx), rtol=1e-6, atol=1e-6)
def test_mie_internal_coeffs(): m = 1.5 + 0.1j x = 50. n_stop = miescatlib.nstop(x) al, bl = miescatlib.scatcoeffs(m, x, n_stop) cl, dl = miescatlib.internal_coeffs(m, x, n_stop) jlx = sph_jn(n_stop, x)[0][1:] jlmx = sph_jn(n_stop, m * x)[0][1:] hlx = jlx + 1.j * sph_yn(n_stop, x)[0][1:] assert_allclose(cl, (jlx - hlx * bl) / jlmx, rtol = 1e-6, atol = 1e-6) assert_allclose(dl, (jlx - hlx * al)/ (m * jlmx), rtol = 1e-6, atol = 1e-6)
def SpherePlaneWave(k, x): """Find acoustic potential from planewave [1,0,0] scattered by sphere of radius 1. Potentials are solved for a points p = r*cos(x) and so r must be the same for all points.""" ka = k kr = k x = np.asarray(x, np.float).reshape(-1, ) theta = np.arccos(x) N = 0 badcells = False, False while any(badcells) == False: N += 100 n = np.arange(N + 1) djnka = sph_jn(N, ka)[1] dynka = sph_yn(N, ka)[1] dhnka = djnka + 1j * dynka jnkr = sph_jn(N, kr)[0] ynkr = sph_yn(N, kr)[0] hnkr = jnkr + 1j * ynkr simplefilter("ignore") pscat = -(1j**n) * (2 * n + 1) * djnka * hnkr / dhnka simplefilter("default") badcells = np.isnan(pscat) + np.isinf(pscat) pscat = np.repeat([pscat], x.size, axis=0) * Pn(N, np.cos(theta)) pscat = pscat.compress(np.logical_not(badcells), axis=1) pinc = np.exp(1j * k * x) return np.sum(pscat, axis=1) + pinc
def SpherePlaneWave2(k, a, r, theta, just_scattered=False): """Find acoustic potential from planewave [1,0,0] scattered by sphere of radius 1.""" ka = k * a x = r * np.cos(theta) N = 0 badcells = False, False while np.any(badcells) == False: N += 100 n = np.arange(N + 1) djnka = sph_jn(N, ka)[1] dynka = sph_yn(N, ka)[1] dhnka = djnka + 1j * dynka djnka = np.repeat([djnka], r.size, axis=0).reshape(r.size, N + 1) dhnka = np.repeat([dhnka], r.size, axis=0).reshape(r.size, N + 1) jnkr = np.vstack([sph_jn(N, kr)[0] for kr in k * r]) ynkr = np.vstack([sph_yn(N, kr)[0] for kr in k * r]) hnkr = jnkr + 1j * ynkr simplefilter("ignore") pscat = -(1j**n) * (2 * n + 1) * djnka * hnkr / dhnka simplefilter("default") badcells = np.isnan(pscat) + np.isinf(pscat) pscat *= Pn(N, np.cos(theta)) pscat = pscat.compress(np.all(np.logical_not(badcells) == True, axis=0), axis=1) if just_scattered: return np.sum(pscat, axis=1) else: return np.sum(pscat, axis=1) + np.exp(1j * k * x)
def calc_phase_shift(self, l, points): """Finds the phase shift of the wavelength using the method described in Gianozzi. Arguments: l: angular momentum number points: the array holding the solution to the Schrodinger equation Returns: delta: the phase shift """ #set up r1 and r2 using a r2 = self.rgrid[-1] wavelength = 2*np.pi/self.ki r1_index = -int(2*wavelength/self.stepsize) r1 = self.rgrid[r1_index] #pick out X(r1) and X(r2) chi2 = points[-1] chi1 = points[r1_index] #find K K = (r2*chi1)/(r1*chi2) #Get correct Bessel functions jl and nl and plug in r values #special.sph_jn(l,k*r) #special.sph_yn(l,k*r) # These functions actually return a list of two arrays: # - an array containing all jn up to l # - an array containing all jn' up to l #tan^-1 of 3.19 jn1 = special.sph_jn(l,self.ki*r1)[0][-1] yn1 = special.sph_yn(l,self.ki*r1)[0][-1] jn2 = special.sph_jn(l,self.ki*r2)[0][-1] yn2 = special.sph_yn(l,self.ki*r2)[0][-1] delta = np.arctan((K*jn2-jn1) / (K*yn2-yn1)) return delta
def SpherePlaneWave2(k,a,r,theta,just_scattered=False): """Find acoustic potential from planewave [1,0,0] scattered by sphere of radius 1.""" ka=k*a x = r*np.cos(theta) N=0 badcells=False,False while np.any(badcells)==False: N += 100 n = np.arange(N+1) djnka = sph_jn(N,ka)[1] dynka = sph_yn(N,ka)[1] dhnka = djnka + 1j*dynka djnka = np.repeat([djnka],r.size,axis=0).reshape(r.size,N+1) dhnka = np.repeat([dhnka],r.size,axis=0).reshape(r.size,N+1) jnkr = np.vstack([sph_jn(N,kr)[0] for kr in k*r]) ynkr = np.vstack([sph_yn(N,kr)[0] for kr in k*r]) hnkr = jnkr + 1j*ynkr simplefilter("ignore") pscat= - (1j**n) * (2*n+1) * djnka * hnkr / dhnka simplefilter("default") badcells = np.isnan(pscat)+np.isinf(pscat) pscat *= Pn(N,np.cos(theta)) pscat = pscat.compress(np.all(np.logical_not(badcells)==True,axis=0),axis=1) if just_scattered: return np.sum(pscat,axis=1) else: return np.sum(pscat,axis=1) + np.exp(1j*k*x)
def calc_phase_shift(self, l, points): """Finds the phase shift of the wavelength using the method described in Gianozzi. Arguments: l: angular momentum number points: the array holding the solution to the Schrodinger equation Returns: delta: the phase shift """ #set up r1 and r2 using a r2 = self.rgrid[-1] wavelength = 2 * np.pi / self.ki r1_index = -int(2 * wavelength / self.stepsize) r1 = self.rgrid[r1_index] #pick out X(r1) and X(r2) chi2 = points[-1] chi1 = points[r1_index] #find K K = (r2 * chi1) / (r1 * chi2) #Get correct Bessel functions jl and nl and plug in r values #special.sph_jn(l,k*r) #special.sph_yn(l,k*r) # These functions actually return a list of two arrays: # - an array containing all jn up to l # - an array containing all jn' up to l #tan^-1 of 3.19 jn1 = special.sph_jn(l, self.ki * r1)[0][-1] yn1 = special.sph_yn(l, self.ki * r1)[0][-1] jn2 = special.sph_jn(l, self.ki * r2)[0][-1] yn2 = special.sph_yn(l, self.ki * r2)[0][-1] delta = np.arctan((K * jn2 - jn1) / (K * yn2 - yn1)) return delta
def SIGMA_TOT( E, U, lmax, h, a ): k = math.sqrt(2*E) JJ = scsp.sph_jn((lmax+2),k*2*a) NN = scsp.sph_yn((lmax+2),k*2*a) sig_l = [] sig_tot = 0. for l in range( 0 , lmax + 1): sig_l.append( SIGMA_L(l, E, U, h, a, JJ[0][l], NN[0][l], JJ[1][l], NN[1][l] ) ) sig_tot += sig_l[l] return [sig_tot , sig_l]
def SIGMA_TOT(E, U, lmax, h, a): k = math.sqrt(2 * E) N_max = 2 * int(a / h) - 5 JJ = scsp.sph_jn((lmax + 2), k * 2 * a) NN = scsp.sph_yn((lmax + 2), k * 2 * a) sig_l = [] sig_tot = 0. for l in range(0, lmax + 1): sig_l.append( SIGMA_L(l, E, U, h, a, JJ[0][l], NN[0][l], JJ[1][l], NN[1][l])) sig_tot += sig_l[l] return [sig_tot, sig_l]
def sigmatot( E ): k = math.sqrt(2*E) siT = 0. lmin = 0 lmax = 7 siI = [] JJ = scsp.sph_jn((lmax+2),k) NN = scsp.sph_yn((lmax+2),k) chi = CHI(E, lmax) for l in range(lmin, lmax+1): siI.append( sigmal( E, l, chi[l] , JJ[0][l], NN[0][l], JJ[1][l], NN[1][l] )) siT += siI[l] return (siT,siI,chi)
def solve(self, E=0.5): e = 5.9 s = 1. # 3.57 A, but we normalized to s r0 = .5 mh = 6.12 # find the position of the initial value for the numerov algorithm r0_pos = bisect_left(self._r, r0) # .... and initialize the solution up to that point using the solution for small r self._u[:r0_pos+1] = map(lambda r: exp(-sqrt(6.12*e/25.)/r**5), self._r[:r0_pos+1]) def solve4l(l): def CombinedPotential(r): return LennardJonesPotential(e, s, r) + l*(l+1)/(mh*r**2) # initialize the (combined) potential self._V = array(map(lambda r: CombinedPotential(r), self._r)) # initialize the k's, based on the potential self._k = mh*(E-self._V) for i in xrange(r0_pos, len(self._r)-1): self._u[i+1] = numerov(self._dr, self._k[i], self._u[i], self._k[i-1], self._u[i-1], self._k[i+1]) l_max = 10 s_tot = 0. for l in range(0, l_max+1): solve4l(l) r1 = self._r[-4] u1 = self._u[-4] r2 = self._r[-1] u2 = self._u[-1] K = r1*u2/(r2*u1) k = sqrt(E*mh) delta = arctan2( K*sph_jn(l, k*r1)[0][l] - sph_jn(l, k*r2)[0][l] , K*sph_yn(l, k*r1)[0][l] - sph_yn(l, k*r2)[0][l] ) s_tot += (2*l + 1)*sin(delta)**2 * 4*pi/k**2 print s_tot return s_tot
def sh2fld (k, clm, r, t, p, reg = True): ''' Expand spherical harmonic coefficients clm for a wave number k over the grid range specified by spherical coordinates (r,t,p). Each coordinate should be a single-dimension array. If reg is False, use a singular expansion. Otherwise, use a regular one. ''' # Pull out the maximum degree and the required matrix leading dimension deg, lda = clm.shape[1], 2 * clm.shape[1] - 1 # If there are not enough harmonic orders, raise an exception if clm.shape[0] < lda: raise IndexError('Not enough harmonic coefficients.') # Otherwise, compress the coefficient matrix to eliminate excess values if clm.shape[0] > lda: clm = np.array([[clm[i,j] for j in range(deg)] for i in harmorder(deg-1)]) # Compute the radial term if reg: # Perform a regular expansion jlr = np.array([spec.sph_jn(deg-1, k*rx)[0] for rx in r]) else: # Perform a singular expansion jlr = np.array([spec.sph_jn(deg-1, k*rx)[0] + 1j * spec.sph_yn(deg-1, k*rx)[0] for rx in r]) # Compute the azimuthal term epm = np.array([[np.exp(1j * m * px) for px in p] for m in harmorder(deg-1)]) shxp = lambda c, y: np.array([[c[m,l] * y[abs(m),l] for l in range(deg)] for m in harmorder(deg-1)]) # Compute the polar term and multiply by harmonic coefficients ytlm = np.array([shxp(clm,poly.legassoc(deg-1,deg-1,tx)) for tx in t]) # Return the product on the specified grid fld = np.tensordot(jlr, np.tensordot(ytlm, epm, axes=(1,0)), axes=(1,1)) return fld.squeeze()
def ScatteringCoeff(incidentDirection): global a, kappa, numTerms Al = np.zeros((numTerms, 2 * numTerms + 1), dtype=np.complex) AA = np.zeros((2, 2), dtype=np.complex) j, jp = special.sph_jn(numTerms - 1, kappa * a) # array of Bessel 1st kind and its derivatives h, hp = special.sph_yn(numTerms - 1, a) # arrays of Bessel 2nd kind and its derivatives theta, phi = thetaphi(incidentDirection) for l in range(numTerms): Y = complexY(l, theta, phi) AA[0, 0], AA[0, 1] = j[l], -h[l] AA[1, 0], AA[1, 1] = kappa * jp[l], -hp[l] for m in np.arange(-l, l + 1): a0lm = pi4 * (1j ** l) * np.conjugate(Y[m + l]) RHS = [a0lm * j[l], a0lm * jp[l]] x = sci.linalg.solve(AA, RHS) # x, info = sci.sparse.linalg.gmres(ScatAmplitude,RHS) Al[l, m + l] = x[1] return Al
def bf_coeff(l, km, k0, etam, eta0, r): """Ratios between (b1lm,f1lm) and a1lm. See the single_spherical_wave_scatter.nb file""" sph_j_kmr = sph_jn(l, km*r) sph_j_k0r = sph_jn(l, k0*r) sph_y_k0r = sph_yn(l, k0*r) jm = sph_j_kmr[0][l] h01 = sph_j_k0r[0][l] + 1j * sph_y_k0r[0][l] h02 = sph_j_k0r[0][l] - 1j * sph_y_k0r[0][l] Jm = jm + km * r * sph_j_kmr[1][l] H01 = h01 + k0 * r * (sph_j_k0r[1][l] + 1j * sph_y_k0r[1][l]) H02 = h02 + k0 * r * (sph_j_k0r[1][l] - 1j * sph_y_k0r[1][l]) denom1 = h01*Jm*k0*eta0 - H01*jm*km*etam b1_a1 = - (h02*Jm*k0*eta0 - H02*jm*km*etam) / denom1 f1_a1 = - k0 * sqrt(eta0*etam) * (H01*h02 - h01*H02) / denom1 denom2 = (H01*jm*km*eta0 - h01*Jm*k0*etam) b2_a2 = - (H02*jm*km*eta0 - h02*Jm*k0*etam) / denom2 f2_a2 = - k0 * sqrt(eta0*etam) * (-H01*h02 + h01*H02) / denom2 return (b1_a1, f1_a1, b2_a2, f2_a2)
def sph_yn_(n, x): return sph_yn(n.astype('l'), x)[0][-1]
def uExactDirichletTrace(self, point): x, y, z = point r = np.sqrt(x**2 + y**2 + z**2) hD, dhD = sph_jn(self.l_max, self.kExt * r) + 1j*sph_yn(self.l_max, self.kExt * r) Y, dY = lpn(self.l_max, x / r) return (self.cDir * hD * Y).sum()
def phase_eq(self,phase,r,l): ph = -2*self.m*self.k0*r**2*self.V(r) ph *= (cos(phase)*sph_jn(l,self.k0*r)[0][l]-sin(phase)*sph_yn(l,self.k0*r)[0][l])**2.0 return (ph)
Vmat = bem.as_matrix(V.weak_form()) Kmat = bem.as_matrix(K.weak_form()) Wmat = bem.as_matrix(W.weak_form()) Mmat = bem.as_matrix(M.weak_form()) # Orthogonality Utemp = Uinc.projections() Err = np.vdot(Utemp, Uinc.coefficients) print abs(np.real(Err) - 1), 'Err Orthogonality' # V j_p, dj_p = sph_jn(p, kappa) y_p, dy_p = sph_yn(p, kappa) h_p = j_p + 1j * y_p dh_p = dj_p + 1j * dy_p #Temp = V * Uinc #Res_V = np.vdot(Uinc.coefficients, Temp.projections()) # Error for Single Layer Temp = np.dot(Vmat, Uinc.coefficients) print Temp Res_V = np.vdot(Uinc.coefficients, Temp) Ref_V = 1j * kappa * j_p[p] * h_p[p] print np.abs(Res_V - Ref_V) / np.abs(Ref_V), 'Error V'
def alt_sph_yn(l, x): yn, dyn = sph_yn(l, x) return x * dyn[-1] + yn[-1]
def f(r): # Sch eqn in Numerov form return 2*(E - V(r)) - L*(L+1)/(r*r) def wf(M, xm): # find w.f. and deriv at xm c = (h*h)/6. wfup, nup = ode.numerov(f, [0,.1], M, xL, h) # 1 step past xm dup = ((1+c*f(xm+h))*wfup[-1] - (1+c*f(xm-h))*wfup[-3])/(h+h) return wfup, dup/wfup[-2] xL, a, M = 0., 10., 200 # limits, matching point h, Lmax, E =(a-xL)/M, 15, 2. # step size, max L, energy k, ps = np.sqrt(2*E), np.zeros(Lmax+1) # wave vector, phase shift if scipy.__version__[0] < '1': jl, dj = sph_jn(Lmax, k*a) # (j_l, j_l') tuple nl, dn = sph_yn(Lmax, k*a) # (n_l, n_l') else: Lrange = range(Lmax + 1) jl, dj = sph_jn(Lrange, k*a, False), sph_jn(Lrange, k*a, True) # (j_l, j_l') nl, dn = sph_yn(Lrange, k*a, False), sph_yn(Lrange, k*a, True) # (n_l, n_l') for L in range(Lmax+1): u, g = wf(M, a) # g= u'/u x = np.arctan(((g*a-1)*jl[L] - k*a*dj[L])/ # phase shift ((g*a-1)*nl[L] - k*a*dn[L])) while (x < 0.0): x += np.pi # handle jumps by pi ps[L] = x theta, sigma = np.linspace(0., np.pi, 100), [] cos, La = np.cos(theta), np.arange(1,2*Lmax+2,2) for x in cos: # calc cross section
def wf(M, xm): # find w.f. and deriv at xm c = (h * h) / 6. wfup, nup = ode.numerov(f, [0, .1], M, xL, h) # 1 step past xm dup = ((1 + c * f(xm + h)) * wfup[-1] - (1 + c * f(xm - h)) * wfup[-3]) / (h + h) return wfup, dup / wfup[-2] xL, a, M = 0., 10., 200 # limits, matching point h, Lmax, E = (a - xL) / M, 15, 2. # step size, max L, energy k, ps = np.sqrt(2 * E), np.zeros(Lmax + 1) # wave vector, phase shift jl, dj = sph_jn(Lmax, k * a) # (j_l, j_l') tuple nl, dn = sph_yn(Lmax, k * a) # (n_l, n_l') for L in range(Lmax + 1): u, g = wf(M, a) # g= u'/u x = np.arctan(((g * a - 1) * jl[L] - k * a * dj[L]) / # phase shift ((g * a - 1) * nl[L] - k * a * dn[L])) while (x < 0.0): x += np.pi # handle jumps by pi ps[L] = x theta, sigma = np.linspace(0., np.pi, 100), [] cos, La = np.cos(theta), np.arange(1, 2 * Lmax + 2, 2) for x in cos: # calc cross section pl = lpn(Lmax, x)[0] # Legendre polynomial fl = La * np.exp(1j * ps) * np.sin(ps) * pl # amplitude sigma.append(np.abs(np.sum(fl))**2 / (k * k))
def f(r): # Sch eqn in Numerov form return 2*(E - V(r)) - L*(L+1)/(r*r) def wf(M, xm): # find w.f. and deriv at xm c = (h*h)/6. wfup, nup = ode.numerov(f, [0,.1], M, xL, h) # 1 step past xm dup = ((1+c*f(xm+h))*wfup[-1] - (1+c*f(xm-h))*wfup[-3])/(h+h) return wfup, dup/wfup[-2] xL, a, M = 0., 10., 200 # limits, matching point h, Lmax, E =(a-xL)/M, 15, 2. # step size, max L, energy k, ps = np.sqrt(2*E), np.zeros(Lmax+1) # wave vector, phase shift jl, dj = sph_jn(Lmax, k*a) # (j_l, j_l') tuple nl, dn = sph_yn(Lmax, k*a) # (n_l, n_l') for L in range(Lmax+1): u, g = wf(M, a) # g= u'/u x = np.arctan(((g*a-1)*jl[L] - k*a*dj[L])/ # phase shift ((g*a-1)*nl[L] - k*a*dn[L])) while (x < 0.0): x += np.pi # handle jumps by pi ps[L] = x theta, sigma = np.linspace(0., np.pi, 100), [] cos, La = np.cos(theta), np.arange(1,2*Lmax+2,2) for x in cos: # calc cross section pl = lpn(Lmax, x)[0] # Legendre polynomial fl = La*np.exp(1j*ps)*np.sin(ps)*pl # amplitude sigma.append(np.abs(np.sum(fl))**2/(k*k))
def nl(l,x): return sps.sph_yn(l,x)[0][-1]
def yl(l,z): """Wrapper for sph_yn (discards the unnecessary data)""" return sph_yn(l, z)[0][l]
def spherical_hankel(n, val, deriv = 0): """spherical hankel function""" a = special.sph_jn(n,val)[deriv][n] b = special.sph_yn(n,val)[deriv][n] return a + 1j*b
# directions of incident wave AL = np.zeros((SphereMesh.shape[0], numTerms, 2 * numTerms + 1), dtype=np.complex) for i in range(SphereMesh.shape[0]): AL[i] = ScatteringCoeff(SphereMesh[i, :]) ScatAmplitude = A(aPointDir, incidentDir) print("\nOUTPUTS:\nScattering amplitude at the point x, A =", ScatAmplitude) uu = TotalField(aPoint, incidentDir) print("Scattering solution at the point x, u =", uu, "\n") # arrays of Bessel 2nd kind and its derivatives H = np.zeros((AnnulusGrid.shape[0], numTerms)) HP = H for i in range(AnnulusGrid.shape[0]): H[i], HP[i] = special.sph_yn(numTerms - 1, np.linalg.norm(AnnulusGrid[i])) # Cube of spherical harmonics YCubeA = complexYCube(SphereMesh) XX = AnnulusGrid for i in range(AnnulusGrid.shape[0]): XX[i] = AnnulusGrid[i] / np.linalg.norm(AnnulusGrid[i]) YCubeX = complexYCube(XX) ################## Minimize to find vector nu ################### # ThetaVec, ThetapVec in M={z: z in C, z.z=1} ThetaVec, ThetapVec, PsiVec = ChooseThetaThetapPsi(100) print("Optimizing...") OptimizedVec = Optimize()
def wf(M, xm): # find w.f. and deriv at xm c = (h * h) / 6. wfup, nup = ode.numerov(f, [0, .1], M, xL, h) # 1 step past xm dup = ((1 + c * f(xm + h)) * wfup[-1] - (1 + c * f(xm - h)) * wfup[-3]) / (h + h) return wfup, dup / wfup[-2] xL, a, M = 0., 10., 200 # limits, matching point h, Lmax, E = (a - xL) / M, 15, 2. # step size, max L, energy k, ps = np.sqrt(2 * E), np.zeros(Lmax + 1) # wave vector, phase shift if scipy.__version__[0] < '1': jl, dj = sph_jn(Lmax, k * a) # (j_l, j_l') tuple nl, dn = sph_yn(Lmax, k * a) # (n_l, n_l') else: Lrange = range(Lmax + 1) jl, dj = sph_jn(Lrange, k * a, False), sph_jn(Lrange, k * a, True) # (j_l, j_l') nl, dn = sph_yn(Lrange, k * a, False), sph_yn(Lrange, k * a, True) # (n_l, n_l') for L in range(Lmax + 1): u, g = wf(M, a) # g= u'/u x = np.arctan(((g * a - 1) * jl[L] - k * a * dj[L]) / # phase shift ((g * a - 1) * nl[L] - k * a * dn[L])) while (x < 0.0): x += np.pi # handle jumps by pi ps[L] = x