Infrared intensities¶
Infrared
is an extension of
Vibrations
, in addition to the
vibrational modes, also the infrared intensities of the modes
are calculated for an Atoms
object.
- class ase.vibrations.Infrared(atoms, indices=None, name='ir', delta=0.01, nfree=2, directions=None)[source]¶
Class for calculating vibrational modes and infrared intensities using finite difference.
The vibrational modes are calculated from a finite difference approximation of the Dynamical matrix and the IR intensities from a finite difference approximation of the gradient of the dipole moment. The method is described in:
D. Porezag, M. R. Pederson: “Infrared intensities and Raman-scattering activities within density-functional theory”, Phys. Rev. B 54, 7830 (1996)
The calculator object (calc) linked to the Atoms object (atoms) must have the attribute:
>>> calc.get_dipole_moment(atoms)
In addition to the methods included in the
Vibrations
class theInfrared
class introduces two new methods; get_spectrum() and write_spectra(). The summary(), get_energies(), get_frequencies(), get_spectrum() and write_spectra() methods all take an optional method keyword. Use method=’Frederiksen’ to use the method described in:T. Frederiksen, M. Paulsson, M. Brandbyge, A. P. Jauho: “Inelastic transport theory from first-principles: methodology and applications for nanoscale devices”, Phys. Rev. B 75, 205413 (2007)
- atoms: Atoms object
The atoms to work on.
- indices: list of int
List of indices of atoms to vibrate. Default behavior is to vibrate all atoms.
- name: str
Name to use for files.
- delta: float
Magnitude of displacements.
- nfree: int
Number of displacements per degree of freedom, 2 or 4 are supported. Default is 2 which will displace each atom +delta and -delta in each cartesian direction.
- directions: list of int
Cartesian coordinates to calculate the gradient of the dipole moment in. For example directions = 2 only dipole moment in the z-direction will be considered, whereas for directions = [0, 1] only the dipole moment in the xy-plane will be considered. Default behavior is to use the dipole moment in all directions.
Example:
>>> from ase.io import read >>> from ase.calculators.vasp import Vasp >>> from ase.vibrations import Infrared >>> water = read('water.traj') # read pre-relaxed structure of water >>> calc = Vasp(prec='Accurate', ... ediff=1E-8, ... isym=0, ... idipol=4, # calculate the total dipole moment ... dipol=water.get_center_of_mass(scaled=True), ... ldipol=True) >>> water.calc = calc >>> ir = Infrared(water) >>> ir.run() >>> ir.summary() ------------------------------------- Mode Frequency Intensity # meV cm^-1 (D/Å)^2 amu^-1 ------------------------------------- 0 16.9i 136.2i 1.6108 1 10.5i 84.9i 2.1682 2 5.1i 41.1i 1.7327 3 0.3i 2.2i 0.0080 4 2.4 19.0 0.1186 5 15.3 123.5 1.4956 6 195.5 1576.7 1.6437 7 458.9 3701.3 0.0284 8 473.0 3814.6 1.1812 ------------------------------------- Zero-point energy: 0.573 eV Static dipole moment: 1.833 D Maximum force on atom in `equilibrium`: 0.0026 eV/Å
This interface now also works for calculator ‘siesta’, (added get_dipole_moment for siesta).
Example:
>>> #!/usr/bin/env python3
>>> from ase.io import read >>> from ase.calculators.siesta import Siesta >>> from ase.vibrations import Infrared
>>> bud = read('bud1.xyz')
>>> calc = Siesta(label='bud', ... meshcutoff=250 * Ry, ... basis='DZP', ... kpts=[1, 1, 1])
>>> calc.set_fdf('DM.MixingWeight', 0.08) >>> calc.set_fdf('DM.NumberPulay', 3) >>> calc.set_fdf('DM.NumberKick', 20) >>> calc.set_fdf('DM.KickMixingWeight', 0.15) >>> calc.set_fdf('SolutionMethod', 'Diagon') >>> calc.set_fdf('MaxSCFIterations', 500) >>> calc.set_fdf('PAO.BasisType', 'split') >>> #50 meV = 0.003674931 * Ry >>> calc.set_fdf('PAO.EnergyShift', 0.003674931 * Ry ) >>> calc.set_fdf('LatticeConstant', 1.000000 * Ang) >>> calc.set_fdf('WriteCoorXmol', 'T')
>>> bud.calc = calc
>>> ir = Infrared(bud) >>> ir.run() >>> ir.summary()
- get_spectrum(start=800, end=4000, npts=None, width=4, type='Gaussian', method='standard', direction='central', intensity_unit='(D/A)2/amu', normalize=False)[source]¶
Get infrared spectrum.
The method returns wavenumbers in cm^-1 with corresponding absolute infrared intensity. Start and end point, and width of the Gaussian/Lorentzian should be given in cm^-1. normalize=True ensures the integral over the peaks to give the intensity.
- write_spectra(out='ir-spectra.dat', start=800, end=4000, npts=None, width=10, type='Gaussian', method='standard', direction='central', intensity_unit='(D/A)2/amu', normalize=False)[source]¶
Write out infrared spectrum to file.
First column is the wavenumber in cm^-1, the second column the absolute infrared intensities, and the third column the absorbance scaled so that data runs from 1 to 0. Start and end point, and width of the Gaussian/Lorentzian should be given in cm^-1.