In [1]:
import numpy as np
import scipy as sp
import matplotlib.pyplot as plt
try:
import thermocepstrum as tc
except ImportError:
from sys import path
path.append('..')
import thermocepstrum as tc
c = plt.rcParams['axes.prop_cycle'].by_key()['color']
In [2]:
%matplotlib notebook
In [3]:
jfile = tc.i_o.TableFile('./data/Silica.dat', group_vectors=True)
In [4]:
jfile.read_datalines(start_step=0, NSTEPS=0, select_ckeys=['flux1'])
Out[4]:
In [5]:
DT_FS = 1.0 # time step [fs]
TEMPERATURE = 1065.705630 # temperature [K]
VOLUME = 3130.431110818 # volume [A^3]
j = tc.HeatCurrent(jfile.data['flux1'], 'metal', DT_FS, TEMPERATURE, VOLUME)
In [6]:
# trajectory
f = plt.figure()
ax = plt.plot(j.timeseries()/1000., j.traj);
plt.xlim([0, 1.0])
plt.xlabel(r'$t$ [ps]')
plt.ylabel(r'$J$ [eV A/ps]');
Compute the Power Spectral Density and filter it for visualization.
In [7]:
# Periodogram with given filtering window width
ax = j.plot_periodogram(PSD_FILTER_W=0.5, kappa_units=True)
print(j.Nyquist_f_THz)
plt.xlim([0, 50])
ax[0].set_ylim([0, 150]);
ax[1].set_ylim([12, 18]);
If the Nyquist frequency is very high (i.e. the sampling time is small), such that the log-spectrum goes to low values, you may want resample your time series to obtain a maximum frequency $f^*$. Before performing that operation, the time series is automatically filtered to reduce the amount of aliasing introduced. Ideally you do not want to go too low in $f^*$. In an intermediate region the results should not change.
To perform resampling you can choose the resampling frequency $f^*$ or the resampling step (TSKIP). If you choose $f^*$, the code will try to choose the closest value allowed.
The resulting PSD is visualized to ensure that the low-frequency region is not affected.
In [8]:
FSTAR_THZ = 28.0
jf, ax = tc.heatcurrent.resample_current(j, fstar_THz=FSTAR_THZ, plot=True, freq_units='thz')
plt.xlim([0, 80])
ax[1].set_ylim([12,18]);
In [9]:
ax = jf.plot_periodogram(PSD_FILTER_W=0.1)
ax[1].set_ylim([12, 18]);
In [10]:
jf.cepstral_analysis()
In [11]:
# Cepstral Coefficients
print('c_k = ', jf.dct.logpsdK)
ax = jf.plot_ck()
ax.set_xlim([0, 50])
ax.set_ylim([-0.5, 0.5])
ax.grid();
In [12]:
# AIC function
f = plt.figure()
plt.plot(jf.dct.aic, '.-', c=c[0])
plt.xlim([0, 200])
plt.ylim([2800, 3000]);
print('K of AIC_min = {:d}'.format(jf.dct.aic_Kmin))
print('AIC_min = {:f}'.format(jf.dct.aic_min))
Plot the thermal conductivity $\kappa$ as a function of the cutoff $P^*$
In [13]:
# L_0 as a function of cutoff K
ax = jf.plot_L0_Pstar()
ax.set_xlim([0, 200])
ax.set_ylim([12.5, 14.5]);
print('K of AIC_min = {:d}'.format(jf.dct.aic_Kmin))
print('AIC_min = {:f}'.format(jf.dct.aic_min))
In [14]:
# kappa as a function of cutoff K
ax = jf.plot_kappa_Pstar()
ax.set_xlim([0,200])
ax.set_ylim([0, 5.0]);
print('K of AIC_min = {:d}'.format(jf.dct.aic_Kmin))
print('AIC_min = {:f}'.format(jf.dct.aic_min))
Print the results :)
In [15]:
print(jf.cepstral_log)
You can now visualize the filtered PSD...
In [16]:
# filtered log-PSD
ax = j.plot_periodogram(0.5, kappa_units=True)
ax = jf.plot_periodogram(0.5, axes=ax, kappa_units=True)
ax = jf.plot_cepstral_spectrum(axes=ax, kappa_units=True)
ax[0].axvline(x = jf.Nyquist_f_THz, ls='--', c='r')
ax[1].axvline(x = jf.Nyquist_f_THz, ls='--', c='r')
plt.xlim([0., 50.])
ax[1].set_ylim([12,18])
ax[0].legend(['original', 'resampled', 'cepstrum-filtered'])
ax[1].legend(['original', 'resampled', 'cepstrum-filtered']);
In [ ]: