Guest User

Acoustic Levitation

a guest
Aug 15th, 2020
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.17 KB | None | 0 0
  1. #!/usr/bin/python3
  2.  
  3. # Acoustic wave propogation and reflection model used for
  4. # predicting pressure inflection points for acoustic levitationp.
  5. # Determines pressure distribution for a given 2D area assuming a
  6. # circular transducer radiation surface and circular flat reflector.
  7.  
  8.  
  9. import pdb
  10. import numpy as np
  11. import matplotlib.pylab as plt
  12. import scipy as sci
  13. ######### MODEL PARAMETERS #####################
  14.  
  15. mm = 1e-3
  16.  
  17. # Grid sizing (mm) - this can be changed
  18. x_min = -10*mm
  19. x_max = 10*mm
  20. z_min = 0
  21. z_max = 15*mm
  22.  
  23. disc = 0.5*mm   # Discretization size - this defines the resolution of the data
  24. R = 5*mm        # Transducer radius (mm)
  25.  
  26. ############################################
  27.  
  28. # Establish THE GRID
  29. x = np.linspace(x_min, x_max, int((x_max-x_min)/disc))
  30. z = np.linspace(z_min, z_max, int((z_max-z_min)/disc))
  31. transducer = np.linspace(-R, R, int((2*R)/disc))
  32.  
  33.  
  34. # Array indices so I can keep track of dimensions
  35. N = int((2*R)/disc)
  36. M = int(len(x)*len(z))
  37. L = int(len(x))
  38. Z = int(len(z))
  39.  
  40. # Distance arrays
  41. r_nm = np.zeros((N, M))
  42. r_im = np.zeros((L, M))
  43. r_in = np.zeros((N, L))
  44.  
  45. # print(the array sizes to get a feel for how long this shit will take to run
  46. print('N: {}'.format(N))
  47. print('M: {}'.format(M))
  48. print('L: {}'.format(L))
  49. print('Z: {}'.format(Z))
  50.  
  51. # DISTANCE ARRAYS ####################################
  52.  
  53. # Calculate r_nm
  54. for i in range(N):
  55.     q = 0
  56.     for j in range(L):
  57.         for k in range(len(z)):
  58.             r_nm[i, q] = np.sqrt((transducer[i]-x[j])**2+(z_max-z[k])**2)
  59.             q = q+1
  60.  
  61.  
  62. # Calculate r_im
  63. for i in range(L):
  64.     q = 0
  65.  
  66.     for j in range(L):
  67.         for k in range(len(z)):
  68.             r_im[i, q] = np.sqrt((x[i]-x[j])**2+(z_min-z[k])**2)
  69.             q = q + 1
  70.  
  71.  
  72. # Calculate r_in
  73. for i in range(N):
  74.     for j in range(L):
  75.         r_in[i, j] = np.sqrt((transducer[i]-x[j])**2+(z_max-z_min)**2)
  76. r_ni = r_in.T
  77.  
  78. ##################################################################
  79.  
  80. # Constants and stuff
  81. # These need to be complex so Python doesn't shit the bed when it sees a complex calculation
  82.  
  83. A_trans = complex(np.pi*R**2, 0)        # Transducer area, m^2
  84. A_refl = complex(np.pi*(x_max/2)**2, 0)  # Reflector area, m^2
  85. rho = complex(1.214, 0)         # Density of air in Raleigh, kg/m^3
  86. c = complex(340.1, 0)           # Speed of sound in air, m/s
  87. f = complex(28000, 0)           # Frequency, hZ
  88. wavelength = complex(c/f, 0)        # Wavelength, m
  89. omega = complex(2*np.pi*f, 0)       # Angular frequency
  90. cells = complex(100, 0)         # Number of discrete cells being used for calculation
  91. sn = A_trans/cells          # Unit cell area for transducer
  92. # Unit cell area for reflector - factor of 4 to keep area/cell same for both
  93. si = A_refl/(cells*4)
  94. D = (omega*rho*c)/wavelength        # Constant used for primary wave
  95. wavenumber = omega/c            # .....it's the wavenumber - k
  96. # Amplitude (m), estimated from http://www.mtiinstruments.com/mtiuniversity/appnotes/mtiuniversity-appnotes-ultrasonic.aspx
  97. U_0 = 0.0000060
  98. E = complex(0, 1)/wavelength        # Constant used for reflected waves
  99.  
  100.  
  101. ################# TRANSFER MATRICIES ##################################################
  102.  
  103. T_TM = np.matrix(np.zeros((N, M)), dtype=complex)
  104. T_TR = np.matrix(np.zeros((N, L)), dtype=complex)
  105. T_RT = np.matrix(np.zeros((L, N)), dtype=complex)
  106. T_RM = np.matrix(np.zeros((L, M)), dtype=complex)
  107.  
  108.  
  109. for i in range(N):
  110.     for j in range(M):
  111.         T_TM[i, j] = (sn*np.exp(complex(0, -1) *
  112.                                 wavenumber*r_nm[i, j]))/r_nm[i, j]
  113.  
  114.     for k in range(L):
  115.         T_TR[i, k] = (sn*np.exp(complex(0, -1) *
  116.                                 wavenumber*r_in[i, k]))/r_in[i, k]
  117.  
  118. for i in range(L):
  119.     for j in range(N):
  120.         T_RT[i, j] = (si*np.exp(complex(0, -1) *
  121.                                 wavenumber*r_ni[i, j]))/r_ni[i, j]
  122.  
  123. for i in range(L):
  124.     # Feedback to keep track of where we are in the calculations, this one can take awhile
  125.  
  126.     for j in range(M):
  127.         if r_im[i, j] == 0.0:
  128.             continue
  129.         T_RM[i, j] = (si*np.exp(complex(0, -1) * wavenumber*r_im[i, j]))/r_im[i, j]
  130.         print('{} {} {}'.format(i,j,T_RM[i,j]))
  131. print('si: {}, wavenumber: {}, r_im[i,j]: {}'.format(
  132.     si, wavenumber, r_im[i, j]))
  133.  
  134. print('si * exp(0,-1): {}'.format(si*np.exp(complex(0, -1))))
  135. print('wavenumber {} '.format(wavenumber))
  136. print('si * exp(0,-1) * wavenumber {}'.format(si*np.exp(complex(0, -1) * wavenumber)))
  137.  
  138.  
  139. # Rotate the matricies so dimensions work out for arithmetic
  140. T_TM = T_TM.T
  141. T_TR = T_TR.T
  142. T_RT = T_RT.T
  143. T_RM = T_RM.T
  144.  
  145. ######################## DISPLACEMENT ARRAY #######################################
  146.  
  147. # U will be the same for every point N on the transducer
  148. U = np.array(np.zeros((N, 1)), dtype=complex)
  149. for i in range(N):
  150.     U[i] = U_0*np.exp(complex(0, omega))
  151.  
  152. ######################### PRESSURE CALCULATIONS #################################
  153.  
  154. # Initial wave propogation + 4 reflected waves - higher order terms can be added or removed for accuracy or efficiency
  155. P = (D*E)*T_RM*(T_TR*U)+(D*E**2)*(T_TM*T_RT)*(T_TR*U)+(D*E**3)*T_RM * \
  156.     (T_TR*T_RT)*(T_TR*U)+(D*E**4)*(T_TM*T_RT)*(T_TR*T_RT)*(T_TR*U)
  157.  
  158. # Reshape the pressure array so Z is up and X is across
  159. P2 = np.array(np.reshape(P, (len(x), len(z))))
  160. P2 = np.transpose(P2)
  161. ###################################################################
  162.  
  163. rho = 1.214
  164. c = 340.1
  165. lamb = 0.0122
  166. omega = 28000
  167. k = omega/c
  168. rad = 2 * np.pi / 180
  169. cell = 100
  170. sn = np.pi*rad**2/cell
  171. u = 0.000006
  172.  
  173.  
  174. p = np.zeros(20)
  175. a = np.zeros(20)
  176. for j in range(20):
  177.     p[j] = omega*rho*c*(1/lamb)*sn*(1/(lamb*(j+1)/2) *
  178.                                     u*np.exp(-i*k*(lamb*(j+1)/2)))
  179.     a[j] = rho*c*(1/lamb)*sn*(1/(lamb*(j+1)/2))*u*np.exp(-i*k*(lamb*(j+1)/2))+omega*rho*c * \
  180.         (1/lamb)*sn*(1/(lamb*(j+1)/2))*u*np.exp(-i*k *
  181.                                                 (lamb*(j+1)/2))*(-i*(lamb*(j+1)/2)*(1/c))*1000
  182.  
  183. # print(p)
  184. # print(a)
  185.  
  186.  
  187. plt.pcolormesh(x, z, P2.real)
  188. plt.title('Pressure Distribution')
  189. plt.xlabel('X (m)')
  190. plt.ylabel('Z (m)')
  191. # Scale the pressure gradients so the colors make sense
  192. plt.clim(min(P.real)/2, -min(P.real)/2.5)
  193. plt.colorbar().set_label('Relative Pressure')
  194. # savefig('odd_Wavelength.png',dpi=300) # Save the image with given parameters
  195. plt.show()
  196.  
Add Comment
Please, Sign In to add comment