def FT_unified(signal, timestep, kwargs): ft_length = kwargs['stop'] - kwargs['start'] if kwargs['FT_method'] == 'rfft': print('rfft ...') single_point = False frequencies = np.fft.rfftfreq(ft_length, timestep)*const.value('Hartree energy')/const.hbar ft = [-np.fft.rfft(sig) for sig in signal] # Pade approximation elif kwargs['FT_method'] == 'pade': print('Pade approximants...') if isinstance(kwargs['pade_ws'], tuple): single_point = False w_start = conv.ev2au(kwargs['pade_ws'][0]) w_stop = conv.ev2au(kwargs['pade_ws'][1]) w_step = conv.ev2au(kwargs['pade_ws'][2]) freq_pade = np.arange(w_start, w_stop, w_step) frequencies = freq_pade *const.value('Hartree energy')/const.hbar ft = tuple([pade(sig, ft_length, timestep, freq_pade, single_point = single_point) for sig in signal]) # print('tuple') else: single_point = True frequencies = [] ft = tuple([pade(sig, ft_length, timestep, 0, single_point = single_point) for sig in signal]) else: raise KeyError("FT_method not known or misspelled. Currently: rfft, pade") return frequencies, ft, single_point
def deriv(self, diff, freq): # take derivative at a specific excitation frequency if self.single_point: W = np.exp(-1j * conv.ev2au(freq) * self.timestep * 2 * np.pi) self.resonancefreq = conv.eV2f(freq) self.a_p = np.asarray([i(W)/j(W)/self.fieldstrength for (i, j) in self.ft_p]).reshape((3,3)) self.a_m = np.asarray([i(W)/j(W)/self.fieldstrength for (i, j) in self.ft_m]).reshape((3,3)) else: # get nearest discretized frequency to the excitation frequency exc_freq_Hz = conv.eV2f(freq) index, self.resonancefreq = find_nearest(self.frequencies, exc_freq_Hz) # print(index,self.resonancefreq) self.a_p = np.asarray([i[index] for i in self.ft_p]).reshape((3,3)) self.a_m = np.asarray([i[index] for i in self.ft_m]).reshape((3,3)) # print('polarizability_p: ', self.a_p) # print('polarizability_m: ', self.a_m) # print('polarizability_m_SI: ', conv.polarizability_au2SI(self.a_m)) # print('mean polarizability_p: ', 1/3*(self.a_p[0,0] + self.a_p[1,1] + self.a_p[2,2])) # print('mean polarizability_m: ', 1/3*(self.a_m[0,0] + self.a_m[1,1] + self.a_m[2,2])) # print('difference: ', self.a_p - self.a_m) # print('diff', diff) self.da = diff_3(self.a_p, self.a_m, diff) self.da_SI = conv.polarizability_deriv_au2SI(self.da / np.sqrt(const.m_e/const.value('atomic mass constant')) ) / np.sqrt(const.m_e) # convert to SI units and account for mass-weighted coordinates print(self.da)
def _scan(self, w): W = np.exp(-1j * conv.ev2au(w) * self.timestep * 2 * np.pi) trace = [i(W)/j(W) for (i, j) in self.ft] f = w*const.e/const.h # convert to Hz [SI] return 4 * np.pi * f / (3 * const.c) * np.imag(trace[0] + trace[1] + trace[2])
def scan_m(self, w): W = np.exp(-1j * conv.ev2au(w) * self.timestep * 2 * np.pi) trace = [i(W)/j(W)/self.fieldstrength for (i, j) in self.ft_m] f = conv.eV2f(w) # convert to Hz [SI] return 4 * np.pi * f / (3 * const.c) * np.imag(trace[0] + trace[1] + trace[2])
def mean_polarizability(self, w, kappa): W = np.exp(-1j * conv.ev2au(w) * self.timestep * 2 * np.pi) alpha = np.asarray([i(W)/j(W) for (i, j) in self.ft])/kappa return alpha