Source code for jarvis.analysis.phonon.ir

"""
Modules for analyzing infrared intensities.

Please find more details in https://doi.org/10.1038/s41524-020-0337-2 .
"""
from jarvis.core.spectrum import Spectrum
import numpy as np


[docs]def normalize_vecs(phonon_eigenvectors, masses): """ Return the eigenvectors after division of each component by sqrt(mass). Adapted from https://github.com/JMSkelton/Phonopy-Spectroscopy/ """ nmodes = len(phonon_eigenvectors) nmasses = len(masses) natoms = nmasses sqrt_masses = np.sqrt(masses) eigendisplacements = np.zeros((nmodes, natoms, 3), dtype=np.float64) for i in range(0, nmodes): eigenvector = phonon_eigenvectors[i] for j in range(0, natoms): eigendisplacements[i, j, :] = np.divide( eigenvector[j], sqrt_masses[j] ) return eigendisplacements
[docs]def ir_intensity( phonon_eigenvectors=[], phonon_eigenvalues=[], masses=[], born_charges=[], smoothen=True, ): """Calculate IR intensity using DFPT.""" eigendisplacements = normalize_vecs(phonon_eigenvectors, masses) becDim1, becDim2, becDim3 = np.shape(born_charges) freq = [] ir_ints = [] for i, v in zip(eigendisplacements, phonon_eigenvalues): eigendisplacement = i eigDim1, eigDim2 = np.shape(eigendisplacement) irIntensity = 0.0 for a in range(0, 3): sumTemp1 = 0.0 for j in range(0, eigDim1): sumTemp2 = 0.0 for b in range(0, 3): sumTemp2 += born_charges[j][a][b] * eigendisplacement[j][b] sumTemp1 += sumTemp2 irIntensity += sumTemp1 ** 2 freq.append(v * 33.35641) # Thz to cm-1 ir_ints.append(irIntensity) if smoothen: freq, ir_ints = Spectrum(x=freq, y=ir_ints).smoothen_spiky_spectrum() return freq, ir_ints
""" if __name__ == "__main__": from jarvis.io.vasp.outputs import Vasprun, Outcar out = Outcar("../../tests/testfiles/io/vasp/OUTCAR.JVASP-39") vrun = Vasprun("../../tests/testfiles/io/vasp/vasprun.xml.JVASP-39") phonon_eigenvectors = vrun.dfpt_data["phonon_eigenvectors"] vrun_eigs = vrun.dfpt_data["phonon_eigenvalues"] phonon_eigenvalues = out.phonon_eigenvalues masses = vrun.dfpt_data["masses"] born_charges = vrun.dfpt_data["born_charges"] x, y = ir_intensity( phonon_eigenvectors=phonon_eigenvectors, phonon_eigenvalues=phonon_eigenvalues, masses=masses, born_charges=born_charges, ) for i, j in zip(x, y): if j > 0.1: print(i, j) print() print(round(y[1], 2)) # for i, j in zip(phonon_eigenvalues, vrun_eigs): # print(i, j) """