Advertisement
Guest User

Untitled

a guest
Jan 25th, 2020
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.03 KB | None | 0 0
  1. import numpy as np
  2. from scipy import sparse
  3. import scipy.sparse.linalg as splin
  4. import matplotlib.pyplot as plt
  5. import scipy.interpolate as inter
  6.  
  7.  
  8. def RK4(f,t,dt,initial): # the classical Runge-Kutta method (stage 4 method)
  9. m = initial.shape[0]
  10. n = int(t/dt)
  11. tlist = np.linspace(0,t,n)
  12. dt = tlist[1] - tlist[0]
  13. y = np.zeros((m,n),float)
  14. y[:,0]= initial
  15. for i in range(0,n-1):
  16. k1 = f(y[:,i]) # Eq. (5.25)
  17. k2 = f(y[:,i] + 0.5*dt*k1) # Eq. (5.26)
  18. k3 = f(y[:,i] + 0.5*dt*k2) # Eq. (5.27)
  19. k4 = f(y[:,i] + dt*k3) # Eq. (5.28)
  20. y[:,i+1] = y[:,i] + (dt/6.0)*(k1 + 2*k2+2*k3 +k4) # Eq. (5.24)
  21.  
  22. return tlist, y
  23.  
  24.  
  25. x0 = -0.15
  26. xN = 0.15
  27.  
  28. y0 = -0.05
  29. yN = 0.05
  30.  
  31. g = 0.03
  32. d = 0.05
  33.  
  34. U = 1
  35.  
  36.  
  37. Mx = 60
  38. My = Mx/3
  39.  
  40. dx = (xN - x0) / Mx #step size in x
  41. dy = (yN - y0) / My #step size in y
  42.  
  43. x = np.linspace(x0 + dx,xN - dx,Mx - 1)
  44. y = np.linspace(y0 + dy,yN - dy,My - 1)
  45.  
  46. lenx = len(x) #length of x
  47. leny = len(y) #length of y
  48.  
  49. def setupA(J,L,dx,dy,x):
  50. N = J*L #NxN matrix size
  51. dia = np.zeros(N,float) #diagonal elemnets, corners
  52. dia[range(0,L)] = -3
  53. dia[range(L,N - L)] = -4
  54. dia[range(N-L,N)] = -3
  55.  
  56. a = -0.055
  57. b = -0.025
  58. c = 0.025
  59. d = 0.055
  60.  
  61. i = 0
  62. for k in x:
  63. if (k >= a and k < b) or (k >= c and k < d):
  64. dia[(i - 1)*L] = -3 #top
  65. dia[(i*L) - 1] = -3 #bot
  66. i += 1
  67. up = np.ones(N,float)
  68. up[range(L,N,L)] = 0
  69.  
  70. dn = np.ones(N,float)
  71. dn[range(L -1, N - 1,L)] = 0
  72.  
  73. offL = np.ones(N,float)
  74. vecs = np.array([offL,dn,dia,up,offL]) #join vecotrs
  75. diags = np.array([-L, -1, 0, 1, L])
  76. A = sparse.spdiags(vecs, diags, N, N) #sparse matrix
  77. A = A.tocsr() #from sparse matrix to a CRS - compressed sparse row
  78. return A
  79.  
  80.  
  81.  
  82.  
  83. def setupboundary(J,L): #Dirichlet boundary conditions
  84. N = J*L # NxN matrix size
  85. a = -0.025
  86. c = 0.025
  87. b = np.zeros(N,float)
  88. i = 0
  89. for k in x:
  90. if k >= a and k < c:
  91. b[(i - 1)*L] = -U #top
  92. b[(i*L) - 1] = -U #bottom
  93. i += 1
  94. return b
  95.  
  96.  
  97. A = setupA(lenx,leny,dx,dy,x)#sparse matrix
  98. b = setupboundary(lenx,leny)
  99.  
  100. sol = splin.spsolve(A,b) #solve sparse
  101. sol = np.reshape(sol,(lenx,leny)) #reshape to 2D
  102. sol = sol.transpose() #transpose
  103.  
  104. dh = dx
  105.  
  106. Ex = np.zeros((leny,lenx)) #field in x
  107. for i in range(0,leny):
  108. for j in range(1,lenx - 1):
  109. Ex[i,j] = -(sol[i,j + 1] - sol[i,j - 1])/(2*dh)
  110.  
  111. Ey = np.zeros((leny,lenx)) #field in y
  112. for i in range(0,lenx):
  113. for j in range(1,leny - 1):
  114. Ey[j,i] = - (sol[j + 1,i] - sol[j - 1,i])/(2*dh)
  115.  
  116. Exint = inter.interp2d(x,y,Ex,kind = 'cubic')
  117. Eyint = inter.interp2d(x,y,Ey,kind = 'cubic')
  118.  
  119.  
  120. XX,YY = np.meshgrid(x,y)
  121. fig,ax = plt.subplots(1,1,figsize = (15,5))
  122. cont = ax.contourf(XX,YY,sol,60)
  123. plt.colorbar(cont)
  124. ax.quiver(XX,YY,Ex,Ey)
  125.  
  126.  
  127. ax.set_title('Electrostatic Potential of an Einzel Lens at %s V' %(U), fontsize = 25) #%s as placeholder, afterwards %(name)
  128. ax.set_xlim(x0,xN)
  129. ax.set_ylim(y0,yN)
  130.  
  131. ax.set_xlabel('$x/m$',fontsize = 15)
  132. ax.set_ylabel('$y/m$',fontsize = 15)
  133. ax.set_aspect('equal')
  134. plt.show()
  135.  
  136. #################
  137.  
  138.  
  139. U = 1.80 #change to get it focused
  140.  
  141.  
  142. A = setupA(lenx,leny,dx,dy,x)#sparse matrix
  143. b = setupboundary(lenx,leny)
  144.  
  145. sol = splin.spsolve(A,b) #solve sparse
  146. sol = np.reshape(sol,(lenx,leny)) #reshape to 2D
  147. sol = sol.transpose() #transpose
  148.  
  149. dh = dx
  150.  
  151. Ex = np.zeros((leny,lenx)) #field in x
  152. for i in range(0,leny):
  153. for j in range(1,lenx - 1):
  154. Ex[i,j] = -(sol[i,j + 1] - sol[i,j - 1])/(2*dh)
  155.  
  156. Ey = np.zeros((leny,lenx)) #field in y
  157. for i in range(0,lenx):
  158. for j in range(1,leny - 1):
  159. Ey[j,i] = - (sol[j + 1,i] - sol[j - 1,i])/(2*dh)
  160.  
  161. Exint = inter.interp2d(x,y,Ex,kind = 'cubic')
  162. Eyint = inter.interp2d(x,y,Ey,kind = 'cubic')
  163.  
  164. q = -1.602e-19 #charge
  165. m = 9.1e-31 #mass
  166. const = q/m
  167.  
  168. XX,YY = np.meshgrid(x,y)
  169. fig,ax = plt.subplots(1,1,figsize = (15,5))
  170. cont = ax.contourf(XX,YY,sol,60)
  171. plt.colorbar(cont)
  172. ax.quiver(XX,YY,Ex,Ey)
  173.  
  174. #trajectory
  175.  
  176. def PewPew(fun):
  177. dy0 = fun[2] #velocity in x
  178. dy1 = fun[3] #velocity in y
  179. dy2 = const*Exint(fun[0],fun[1])[0] #acceleration in x [0] to take the value instead of array
  180. dy3 = const*Eyint(fun[0],fun[1])[0] #acceleration in y
  181. return np.array([dy0,dy1,dy2,dy3])
  182.  
  183. xtra = -0.15
  184. ytra = np.linspace(0.03,-0.03,13)
  185. vxtra = 0.5e6
  186. vytra = 0
  187.  
  188. tfinal = 0.3/vxtra
  189. dt = tfinal/lenx
  190.  
  191.  
  192.  
  193. for i in ytra:
  194. initial = np.array([xtra,i,vxtra,vytra])
  195. tRK4,yRK4 = RK4(PewPew,tfinal,dt,initial)
  196. ax.plot(yRK4[0,:],yRK4[1,:],'-r')
  197.  
  198. ax.set_title('The Trajectory of Electrons through an Einzel Lens at %s V' %(U), fontsize = 25) #%s as placeholder, afterwards %(name)
  199. ax.set_xlim(x0,xN)
  200. ax.set_ylim(y0,yN)
  201.  
  202. ax.set_xlabel('$x/m$',fontsize = 15)
  203. ax.set_ylabel('$y/m$',fontsize = 15)
  204. ax.set_aspect('equal')
  205. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement