Source code for mstm_studio.diel_size_correction

import numpy as np
from mstm_studio.mstm_spectrum import Material


[docs]class SizeCorrectedMaterial(Material): def __init__(self, file_name, wls=None, nk=None, eps=None, omega_p=10.0, gamma_b=0.1, v_Fermi=1.0, sc_C=0.0): ''' Create material with correction to the finite crystal size. Only life-time limit (~1/gamma) is considered. This should be sufficient for the sizes above ~2 nm. The particles smaller than ~2 nm require more sofisticated modifications (band gap, etc.) Parameters: file_name, wls, nk, eps: same meanining as for Material Parameters for size correction: omega_p: plasma frequency (bulk) [eV] gamma_b: life-time broadening (bulk) [eV] v_Fermi: Fermi velocity (bulk) [nm/fs] sc_C: size-corr. adj. parameter [unitless] size of the particle is specified as `self.D` ''' super().__init__(file_name, wls, nk, eps) self.omega_p = omega_p self.gamma_b = gamma_b self.v_Fermi = v_Fermi self.sc_C = sc_C if np.abs(sc_C) < 1e-3: print('WARNING: Size correction parameters are not set') self.D = 1000
[docs] def get_gamma_corr(self): ''' correction to the life time energy broadening (gamma) in the Drude low induced by the finite particle size ''' vF = self.v_Fermi / 1.6 # Fermi vel. in [nm*eV] return self.sc_C * 2 * vF / self.D
def _correction(self, wls): # size is taken from self.D variable if self.D > 100: # don't consider very big particles return 0 omega = 1240 / wls # nm -> eV # correction to gamma due to mean free path limit by size gamma_corr = self.get_gamma_corr() return self.omega_p**2 / omega * \ (1 / (omega + 1j * self.gamma_b) - 1 / (omega + 1j * (self.gamma_b + gamma_corr))) def set_size(self, D): if D > 0: self.D = D else: self.D = None def get_n(self, wls): if self.D is None: return super().get_n(wls) n = super().get_n(wls) k = super().get_k(wls) eps = (n + 1j*k)**2 eps += self._correction(wls) mod = np.absolute(eps) n = np.sqrt((mod + np.real(eps)) / 2) return n def get_k(self, wls): if self.D is None: return super().get_k(wls) n = super().get_n(wls) k = super().get_k(wls) eps = (n + 1j*k)**2 eps += self._correction(wls) mod = np.absolute(eps) k = np.sqrt((mod - np.real(eps)) / 2) return k
[docs]class SizeCorrectedGold(SizeCorrectedMaterial): def __init__(self, file_name, wls=None, nk=None, eps=None): ''' Size correction for gold dielectric function (mean free path is limited by particle size) according to A. Derkachova, K. Kolwas, I. Demchenko Plasmonics, 2016, 11, 941 doi: <10.1007/s11468-015-0128-7> ''' super().__init__(file_name, wls, nk, eps, omega_p=8.6, gamma_b=0.07, v_Fermi=1.4, sc_C=0.3)
[docs]class SizeCorrectedSilver(SizeCorrectedMaterial): def __init__(self, file_name, wls=None, nk=None, eps=None): ''' Size correction for gold dielectric function (mean free path is limited by particle size) according to J.M.J. Santillán, F.A. Videla, M.B.F. van Raap, D. Muraca, L.B. Scaffardi, D.C. Schinca J. Phys. D: Appl. Phys., 2013, 46, 435301 doi: <10.1088/0022-3727/46/43/435301> ''' super().__init__(file_name, wls, nk, eps, omega_p=8.9, gamma_b=0.111, v_Fermi=1.41, sc_C=0.8)
if __name__ == '__main__': import matplotlib.pyplot as plt from mstm_studio.contributions import MieSingleSphere wls = np.arange(300, 800, 1) ### Gold ### matAu = Material('nk/etaGold.txt') matAu3nm = SizeCorrectedGold('nk/etaGold.txt') if False: n = matAu.get_n(wls) k = matAu.get_k(wls) epsAu = (n + 1j * k)**2 matAu3nm.set_size(3) n = matAu3nm.get_n(wls) k = matAu3nm.get_k(wls) epsAu3nm = (n + 1j * k)**2 # plt.plot(wls, matAu.get_n(wls), label='n') plt.plot(1240/wls, np.imag(epsAu), label='bulk') plt.plot(1240/wls, np.imag(epsAu3nm), label='3nm') plt.xlabel('E, eV') plt.ylabel('Im eps') plt.legend() plt.show() plt.plot(1240/wls, np.real(epsAu), label='bulk') plt.plot(1240/wls, np.real(epsAu3nm), label='3nm') plt.xlabel('E, eV') plt.legend() plt.show() plt.plot(wls, matAu.get_n(wls), label='bulk') plt.plot(wls, matAu3nm.get_n(wls), label='3nm') plt.xlabel('Wavelength, nm') plt.ylabel('n') plt.legend() plt.show() plt.plot(wls, matAu.get_k(wls), label='bulk') plt.plot(wls, matAu3nm.get_k(wls), label='3nm') plt.xlabel('Wavelength, nm') plt.ylabel('k') plt.show() D = 3 mie = MieSingleSphere(wavelengths=wls, name='ExtraContrib') mie.set_material(material=matAu, matrix=1.5) ext = mie.calculate(values=[1, D]) mie = MieSingleSphere(wavelengths=wls, name='ExtraContrib') matAu3nm.D = D mie.set_material(material=matAu3nm, matrix=1.5) extcorr = mie.calculate(values=[1, D]) plt.plot(wls, ext, label='%.0fnm, bulk' % D) plt.plot(wls, extcorr, # * np.sum(ext) / np.sum(extcorr), label='%.0fnm, corr.' % D) plt.xlabel('Wavelength, nm') plt.ylabel('Extinction') plt.legend() plt.savefig('Au%.0fnm_bulk_vs_sizecorr.png' % D) plt.show() ### Silver ### matAg = Material('nk/etaSilver.txt') matAg3nm = SizeCorrectedSilver('nk/etaSilver.txt') mie = MieSingleSphere(wavelengths=wls, name='ExtraContrib') mie.set_material(material=matAg, matrix=1.5) ext = mie.calculate(values=[1, D]) mie = MieSingleSphere(wavelengths=wls, name='ExtraContrib') matAg3nm.D = D mie.set_material(material=matAg3nm, matrix=1.5) extcorr = mie.calculate(values=[1, D]) plt.plot(wls, ext, label='%.0fnm, bulk' % D) plt.plot(wls, extcorr, # * np.sum(ext) / np.sum(extcorr), label='%.0fnm, corr.' % D) plt.xlabel('Wavelength, nm') plt.ylabel('Extinction') plt.legend() plt.savefig('Ag%.0fnm_bulk_vs_sizecorr.png' % D) plt.show() print('See you!')