suppFig6-Drude.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #!/usr/bin/env python3
  2. # -*- coding: UTF-8 -*-
  3. import cmath
  4. import numpy as np
  5. import scipy.io
  6. from matplotlib import pyplot as plt
  7. from optical_constants import read_refractive_index_from_yaml as read_nk
  8. from scattnlay import mesomie, mie
  9. # shell 0.4-0.6 nm
  10. # omega_p goes down
  11. shell_h = 0.4
  12. from_disk = np.loadtxt('silver-d_perp_interpolated.txt')
  13. omega_star_ratio = from_disk[0, :]
  14. d_perp = from_disk[1, :] + 1j*from_disk[2, :]
  15. from_disk = np.loadtxt('silver-d_parl_interpolated.txt')
  16. d_parl = from_disk[1, :] + 1j*from_disk[2, :]
  17. c = 299792458 # m/s
  18. h_reduced = 6.5821e-16 # eV s
  19. omega_p = 9.02 # eV
  20. omega_p_star = 3.81 # eV
  21. gamma = 0.15 # eV
  22. eps_inf_drud = 4.65
  23. # eps_inf = 4.65
  24. eps_d = 1
  25. R = 2.5
  26. y_min = 0
  27. y_max = 2
  28. min_lim_omega_star_ratio = 0.87
  29. max_lim_omega_star_ratio = 0.99
  30. # min_lim_omega_ratio = min_lim_omega_star_ratio * omega_p_star/omega_p
  31. # max_lim_omega_ratio = max_lim_omega_star_ratio * omega_p_star/omega_p
  32. # 2 pi / lambda = (omega/c) /h_reduced
  33. WL = 2*np.pi/((omega_star_ratio * omega_p_star/c)/h_reduced)*1e6 # mkm
  34. min_WL_available = 0.1879
  35. max_WL_available = 1.9370
  36. WL[WL < min_WL_available] = min_WL_available
  37. WL[WL > max_WL_available] = max_WL_available
  38. index_Ag = read_nk('Ag-Johnson-1972.yml', WL, kind=1)
  39. eps_Ag = index_Ag**2
  40. # print(index_Ag)
  41. factor = 1
  42. def eps_m(omega, eps_inf, omega_p_local):
  43. return eps_inf - omega_p_local * omega_p_local / (omega*omega + 1j*omega*gamma*factor)
  44. def eps_inf(omega, eps_exp):
  45. return eps_exp + omega_p * omega_p / (omega*omega + 1j*omega*gamma*factor)
  46. Qext = []
  47. Qext_mie = []
  48. Qext_drude_nc = []
  49. om_rat_plot = []
  50. eps_inf_drude = []
  51. eps_m_drude = []
  52. for i in range(len(omega_star_ratio)):
  53. om_star_rat = omega_star_ratio[i]
  54. if (om_star_rat < min_lim_omega_star_ratio
  55. or om_star_rat > max_lim_omega_star_ratio):
  56. continue
  57. omega = om_star_rat*omega_p_star
  58. WL_mkm = 2*np.pi/((omega/c)/h_reduced)*1e6
  59. if WL_mkm < min_WL_available or WL_mkm > max_WL_available:
  60. continue
  61. x_const = (omega/c) * 1e-9/h_reduced
  62. x = R * x_const
  63. m = index_Ag[i, 1]
  64. eps_m_drude.append(m**2)
  65. eps_inf_drude.append(eps_inf(omega, m**2))
  66. m_drude = cmath.sqrt(eps_m(omega, eps_inf(omega, m**2), omega_p))
  67. # m_drude = cmath.sqrt(eps_m(omega, eps_inf_drud, omega_p))
  68. # m_drude = cmath.sqrt(eps_inf(omega, m**2))
  69. print(x, m)
  70. # m = m_drude
  71. mesomie.calc_ab(R*10, # R in angstrem
  72. x, # xd
  73. x * m, # xm
  74. 1, # eps_d
  75. m * m, # eps_m
  76. d_parl[i], # d_parallel
  77. d_perp[i]) # d_perp
  78. mesomie.calc_Q()
  79. Qext.append(mesomie.GetQext())
  80. mie.SetLayersSize(x)
  81. mie.SetLayersIndex(m)
  82. mie.RunMieCalculation()
  83. Qext_mie.append(mie.GetQext())
  84. # m = m_drude
  85. # mesomie.calc_ab(R*10, # R in angstrem
  86. # x, # xd
  87. # x * m, # xm
  88. # 1, # eps_d
  89. # m * m, # eps_m
  90. # d_parl[i], # d_parallel
  91. # d_perp[i]) # d_perp
  92. # mesomie.calc_Q()
  93. # Qext_drude_nc.append(mesomie.GetQext())
  94. # print(x, m, Qext[-1] - mie.GetQext())
  95. om_rat_plot.append(om_star_rat)
  96. plt.plot(om_rat_plot, Qext_mie,
  97. label='classic', color='black', lw=4)
  98. # plt.plot(om_rat_plot, np.real(eps_inf_drude),
  99. # label='real drude', color='blue', lw=1)
  100. # plt.plot(om_rat_plot, np.imag(eps_inf_drude),
  101. # label='imag drude', color='red', lw=1)
  102. # plt.plot(om_rat_plot, np.real(eps_m_drude),
  103. # label='real drude', color='blue', lw=2)
  104. # plt.plot(om_rat_plot, np.imag(eps_m_drude),
  105. # label='imag drude', color='red', lw=2)
  106. plt.plot(om_rat_plot, Qext,
  107. label='non-classic', color='red', lw=4)
  108. # plt.plot(om_rat_plot, Qext_drude_nc,
  109. # label='non-classic drude fixed\nomega_p = 9.02 eV\ngamma = 0.15eV\neps_inf_drud = 4.65', color='blue', lw=2)
  110. for j in range(7):
  111. Qext_drude = []
  112. step = 0.02
  113. for i in range(len(omega_star_ratio)):
  114. om_star_rat = omega_star_ratio[i]
  115. if (om_star_rat < min_lim_omega_star_ratio
  116. or om_star_rat > max_lim_omega_star_ratio):
  117. continue
  118. omega = om_star_rat*omega_p_star
  119. WL_mkm = 2*np.pi/((omega/c)/h_reduced)*1e6
  120. if WL_mkm < min_WL_available or WL_mkm > max_WL_available:
  121. continue
  122. x_const = (omega/c) * 1e-9/h_reduced
  123. x_cs = [(R-shell_h) * x_const, R * x_const],
  124. m = index_Ag[i, 1]
  125. m_drude = cmath.sqrt(eps_m(omega, eps_inf(omega, m**2), omega_p))
  126. m_drude_shell = cmath.sqrt(
  127. eps_m(omega, eps_inf(omega, m**2), omega_p*(0.96+step*j)))
  128. m_cs = [m_drude, m_drude_shell]
  129. mie.SetLayersSize(x_cs)
  130. mie.SetLayersIndex(m_cs)
  131. mie.RunMieCalculation()
  132. Qext_drude.append(mie.GetQext())
  133. plt.plot(om_rat_plot, Qext_drude,
  134. label=f'omega_p*{((0.96+step*j)*100)/100}', color='gray', lw=2)
  135. plt.legend()
  136. # plt.yscale('log')
  137. plt.xlim((min_lim_omega_star_ratio, max_lim_omega_star_ratio))
  138. # plt.ylim((y_min, y_max))
  139. plt.title(
  140. "R="+str(R)+f'\nfor core-shell totalR is the same,\nshell_h={shell_h}')
  141. plt.show()