efficiency-plasmon-plot.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. #!/usr/bin/env python3
  2. # -*- coding: UTF-8 -*-
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. import os
  6. c = 299792458
  7. pi = np.pi
  8. verbose = 6
  9. def read_data(dirname, distance, zshift):
  10. media = [1,2] # 1 - positive zshift, 2 - negative (need to add a minus sign for real shift).
  11. #min_mesh_step = 2.5 #nm
  12. data = []
  13. data.append([])
  14. for x in distance:
  15. data.append([])
  16. data[x].append([])
  17. for m in media:
  18. data[x].append([])
  19. for z in zshift:
  20. monitor_name = "mon_x"+str(x)+"mkm_media"+str(m)+"_zshift"+z+"nm"
  21. data[x][m].append(
  22. np.transpose(
  23. np.genfromtxt(dirname+"/"+monitor_name+".txt", delimiter=", ",skip_header=1
  24. ,dtype=None, encoding = None
  25. , converters={0: lambda s: complex(s),
  26. 1: lambda s: complex(s),
  27. 2: lambda s: complex(s.replace('i', 'j')),
  28. 3: lambda s: complex(s.replace('i', 'j')),
  29. 4: lambda s: complex(s.replace('i', 'j')),
  30. 5: lambda s: complex(s.replace('i', 'j')),
  31. 6: lambda s: complex(s.replace('i', 'j')),
  32. 7: lambda s: complex(s.replace('i', 'j')),
  33. 8: lambda s: complex(s.replace('i', 'j'))
  34. }
  35. )
  36. )
  37. )
  38. return data
  39. def find_nearest(array,value):
  40. idx = (np.abs(array-value)).argmin()
  41. return array[idx],idx
  42. def get_WLs_idx(WLs, data):
  43. dist = 1 #mkm
  44. mmedia = 1 # vacuum
  45. shift = 1 # one mesh step
  46. WLs_idx = []
  47. for wl in WLs:
  48. val, idx = find_nearest(data[dist][mmedia][shift][0,:],wl*1e-9)
  49. WLs_idx.append(idx)
  50. return WLs_idx
  51. def check_field_match(data_in_air, data_in_gold,wl_idx,z_vec,kappa1,kappa2,eps2):
  52. H1 = data_in_air[:,6,wl_idx]
  53. H2 = data_in_gold[:,6,wl_idx]
  54. E1 = data_in_air[:,4,wl_idx]
  55. E2 = data_in_gold[:,4,wl_idx]
  56. for i in range(len(z_vec)):
  57. z = z_vec[i]*1e-9
  58. if verbose > 8: print("z =",z)
  59. H1_0 = H1[i]/np.exp(-kappa1[wl_idx]*z)
  60. H2_0 = H2[i]/np.exp(-kappa2[wl_idx]*z)
  61. E1_0 = E1[i]/np.exp(-kappa1[wl_idx]*z)
  62. E2_0 = E2[i]/np.exp(-kappa2[wl_idx]*z)
  63. E2_0e = E2[i]/np.exp(-kappa2[wl_idx]*z)*eps2[wl_idx]
  64. if verbose > 8:
  65. print("H0 air (%5.4g %+5.4gj)"%(np.real(H1_0), np.imag(H1_0)),
  66. " from H1 (%5.4g %+5.4gj)"%(np.real(H1[i]), np.imag(H1[i])))
  67. print("H0 gold (%5.4g %+5.4gj)"%(np.real(H2_0), np.imag(H2_0)),
  68. " from H2 (%5.4g %+5.4gj)"%(np.real(H2[i]), np.imag(H2[i])))
  69. print("E0 air (%5.4g %+5.4gj)"%(np.real(E1_0), np.imag(E1_0)),
  70. " from E1 (%5.4g %+5.4gj)"%(np.real(E1[i]), np.imag(E1[i])))
  71. print("E0*eps2 (%5.4g %+5.4gj)"%(np.real(E2_0e), np.imag(E2_0e)),
  72. " from E2 (%5.4g %+5.4gj)"%(np.real(E2[i]), np.imag(E2[i])))
  73. print("E0 gold (%5.4g %+5.4gj)"%(np.real(E2_0), np.imag(E2_0)))
  74. def analyze(data, dist, z_vec, wl_idx):
  75. ''' dist in mkm!!!
  76. '''
  77. #data = [dist][mmedia][shift] "lambda, dip.power, Ex, Ey, Ez, Hx, Hy, Hz, n_Au"
  78. # 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 "
  79. data_in_air = np.array(data[dist][1])
  80. data_in_gold = np.array(data[dist][2])
  81. lambd = data_in_air[0][0,:]
  82. omega = 2*pi*c/lambd
  83. dip_power = data_in_air[0][1,:]
  84. Ex = data_in_air[0,2,0]
  85. Ey = data_in_air[0,3,0]
  86. Ez = data_in_air[0,4,0]
  87. Hx = data_in_air[0,5,0]
  88. Hy = data_in_air[0,6,0]
  89. Hz = data_in_air[0,7,0]
  90. E = np.array([Ex,Ey,Ez])
  91. H = np.array([Hx,Hy,Hz])
  92. print("S from full field",np.real(np.cross(E,np.conj(H))))
  93. eps1 = complex(1)
  94. n_Au = data_in_air[0][8,:]
  95. eps2 = n_Au**2
  96. k_0 = omega/c #air
  97. k_spp = k_0*np.sqrt(eps1*eps2/(eps1+eps2))
  98. kappa1= np.sqrt(k_spp**2 - eps1*k_0**2)
  99. kappa2= np.sqrt(k_spp**2 - eps2*k_0**2)
  100. print(1e9*lambd[9])
  101. print(1e9/kappa1[9])
  102. print(1e9/kappa2[9])
  103. check_field_match(data_in_air, data_in_gold,wl_idx,z_vec,kappa1,kappa2,eps2)
  104. H1 = data_in_air[:,6]
  105. E1 = data_in_air[:,4]
  106. z = z_vec[0]*1e-9
  107. if verbose > 5: print("Using data from air monitor at z =",z)
  108. H1_0 = H1[0]/np.exp(-kappa1*z)
  109. E1_0 = E1[0]/np.exp(-kappa1*z)
  110. E2_0 = E1[0]/eps2
  111. if verbose > 5:
  112. print("H0 air (%5.4g %+5.4gj)"%(np.real(H1_0[wl_idx]), np.imag(H1_0[wl_idx])),
  113. " from H1 (%5.4g %+5.4gj)"%(np.real(H1[0][wl_idx]), np.imag(H1[0][wl_idx])))
  114. print("E0 air (%5.4g %+5.4gj)"%(np.real(E1_0[wl_idx]), np.imag(E1_0[wl_idx])),
  115. " from E1 (%5.4g %+5.4gj)"%(np.real(E1[0][wl_idx]), np.imag(E1[0][wl_idx])))
  116. print("E0 gold (%5.4g %+5.4gj)"%(np.real(E2_0[wl_idx]), np.imag(E2_0[wl_idx])), " from E1")
  117. R = dist*1e-6
  118. print("R =",R)
  119. #plasmon_power = 1.0/2.0 * np.real( E1[0] * np.conj(H1[0])) # TODO check minus sign!!
  120. plasmon_power = -1.0/2.0 * 2.0*np.pi*R * ( # TODO check minus sign!!
  121. np.real( E1_0 * np.conj(H1_0) )
  122. / (2.0 * np.real(kappa1))
  123. +
  124. np.real( E2_0 * np.conj(H1_0) )
  125. / (2.0 * np.real(kappa2))
  126. )* np.exp( 2.0*np.imag(k_spp)*R ) # TODO check minus sign!!
  127. #print(np.abs(plasmon_power/ dip_power))
  128. eta0 = plasmon_power[0]/ dip_power[0] *100
  129. ppw = plasmon_power[0]
  130. print("\n")
  131. print(dirname)
  132. print("Power: plasmon %4.3g W of dipoles %4.3g W, efficiency %5.3g%% from:"%(ppw, float(np.abs(dip_power[0])),float(np.abs( eta0))), ppw, eta0)
  133. plt.plot(lambd*1e9, plasmon_power/ dip_power)
  134. np.save(dirname,np.real(plasmon_power/ dip_power))
  135. #plt.ylim(0,0.04)
  136. plt.xlim(550,800)
  137. #plt.plot(lambd*1e9, np.real(eps2))
  138. # plt.plot(lambd*1e9, np.real(k_spp))
  139. # plt.plot(lambd*1e9, k_0)
  140. #plt.semilogy(lambd*1e9, np.absolute(plasmon_power/ dip_power))
  141. # # legend = []
  142. # # legend.append(zshift[shift]+"@"+str(WLs[i])+" nm")
  143. # # plt.legend(legend)
  144. # # #plt.xlabel(r'THz')
  145. plt.xlabel(r'$\lambda$, nm')
  146. plt.ylabel(r'$P_{spp}/P_{dipole}$',labelpad=-5)
  147. #plt.title(' R = '+str(core_r)+' nm')
  148. plt.savefig(dirname+"_power_ratio."+file_ext)
  149. plt.clf()
  150. plt.close()
  151. file_ext="png"
  152. #dirname="template-dipole-on-sphere-on-surf-z.fsp.results"
  153. #dirname="Au-JC-R100-Au-JC.fsp.results"
  154. #dirname="Au-McPeak-R100-Si-Green.fsp.results"
  155. #dirname="Au-McPeak-R100-Au-McPeak.fsp.results"
  156. #dirname="sub-Au-R100-Si-wl450-800-sep10nm.fsp.results"
  157. #dirname="bg-Au-sub-Au-dipole-W.fsp.results"
  158. #dirname="bg-Au-sub-Si-dipole-W.fsp.results"
  159. #dirname="bg-Au-sub-dipole-W.fsp.results"
  160. # dirname=""
  161. # dirname=""
  162. # dirname=""
  163. # dirname=""
  164. # dirname=""
  165. # dirname=""
  166. # dirname=""
  167. #dirname="bg-Au-sub-Si-dipole-Au.fsp.results"
  168. #dirname="bg-Au-sub-dipole-Au.fsp.results"
  169. #dirname="bg-Au-sub-Au-dipole-Au.fsp.results"
  170. #dirname="Au-McPeak-R0.fsp.results"
  171. #dirname="Au-McPeak-R100-Si-Green-1500.fsp.results"
  172. #dirname="Au-McPeak-R100-Si-Green-1500-l.fsp.results"
  173. #dirname="Au-McPeak-R50-Si-Green-1500-l.fsp.results"
  174. #dirname="Au-sub-dipole.fsp.results"
  175. #dirname="Au-sub-dipole-W.fsp.results"
  176. #dirname="Au-sub-Au-dipole-W.fsp.results"
  177. #dirname="Au-sub-Si-dipole-W.fsp.results"
  178. def main (dirname):
  179. distance = [1,2,3,4,5,6,7,8,9,10] #mkm
  180. zshift = ["5","20"]
  181. # zshift = ["5","20","200","400","600"]
  182. z_vec = [int(val) for val in zshift]
  183. data = read_data(dirname, distance, zshift)
  184. #WLs=[300,350,400,450,600,700,800]
  185. #WLs=[600,700, 800, 450]
  186. WLs=[800]#,1500]#, 450]
  187. WLs_idx = get_WLs_idx(WLs, data)
  188. dist = 10 #mkm
  189. wl_idx = WLs_idx[0]
  190. analyze(data, dist, z_vec, wl_idx)
  191. # legend = []
  192. # mmedia = 1
  193. # for shift in range(len(zshift)):
  194. # for i in range(len(WLs)):
  195. # pl_data = []
  196. # idx = WLs_idx[i]
  197. # legend.append(zshift[shift]+"@"+str(WLs[i])+" nm")
  198. # for dist in distance:
  199. # pl_data.append(np.absolute(data[dist][mmedia][shift][2,idx]*np.sqrt(dist)))
  200. # print(len(pl_data))
  201. # plt.semilogy(distance, pl_data,marker="o")
  202. # plt.legend(legend)
  203. # # #plt.xlabel(r'THz')
  204. # plt.xlabel(r'Monitor R, $\mu$m')
  205. # plt.ylabel(r'$Abs(E_x) \sqrt{R}$',labelpad=-5)
  206. # # plt.title(' r = '+str(core_r))
  207. # plt.savefig(dirname+"_WLs."+file_ext)
  208. # plt.clf()
  209. # plt.close()
  210. from glob import glob
  211. paths = glob('*.results')
  212. for dirname in paths:
  213. main(dirname)
  214. # dir_list = next(os.walk('.'))[1]
  215. # print(dir_list)
  216. #main()