Table Of Contents

Search

Enter search terms or a module, class or function name.

Source code for panther.panther


'Python package for Anharmonic Thermochemistry'

from __future__ import print_function, division

from pprint import pprint

from scipy.constants import Planck, value

import numpy as np

from ase.io.vasp import read_vasp_out

from .io import parse_arguments, read_vasp_hessian
from .vibrations import harmonic_vibrational_analysis
from .anharmonicity import anharmonic_frequencies, merge_vibs
from .thermochemistry import Thermochemistry, AnharmonicThermo


[docs]def temperature_range(conditions): ''' Calculate the temperature grid from the input values and return them as numpy array Parameters ---------- conditions : dict Variable for conditions read from the input/config Returns ------- temps : numpy.array Array with the temperature grid ''' epsilon = np.finfo(np.float).eps if np.abs(conditions['Tinitial'] - conditions['Tfinal']) > epsilon: if np.abs(conditions['Tstep']) > epsilon: num = int((conditions['Tfinal'] - conditions['Tinitial'])/conditions['Tstep']) + 1 temps = np.linspace(conditions['Tinitial'], conditions['Tfinal'], num) else: temps = np.array([conditions['Tinitial'], conditions['Tfinal']]) else: temps = np.array([conditions['Tinitial']]) return temps
[docs]def main(): '''The main Thermo program''' args, conditions, job, system = parse_arguments() pprint(conditions) pprint(job) pprint(system) if args.command == 'harmonic': if job['code'] == 'VASP': atoms = read_vasp_out('OUTCAR', index=0) hessian = read_vasp_hessian('OUTCAR', symmetrize=True, convert_to_au=True) else: raise NotImplementedError('Code {} is not supported yet.'.format(job['code'])) freqs, normal_modes = harmonic_vibrational_analysis(hessian, atoms, job['proj_translations'], job['proj_rotations']) # save the freqs and normal modes in atomic units print('INFO: Saving vibrational frequencies to: frequencies.npy') np.save('frequencies', freqs) print('INFO: Saving vibrational normal modes to: normal_modes.npy') np.save('normal_modes', normal_modes) # convert the frequencies to inverse centimeters freqs = 0.01 * value('hartree-inverse meter relationship') * freqs print('\n' + ' Vibrational frequencies in [cm^-1] '.center(50, '='), end='\n\n') print(' {0:^20s} {1:^20s}'.format('real', 'imag')) for i, v in enumerate(freqs, start=1): print('{0:5d} : '.format(i), '{0:20.10f} {1:20.10f}'.format(v.real, v.imag)) # convert frequencies from [cm^-1] to [Hz] and get vib. energies in Joules vibenergies = Planck * freqs.real * 100.0 * value('inverse meter-hertz relationship') vibenergies = vibenergies[vibenergies > 0.0] thermo = Thermochemistry(vibenergies, atoms, phase=system['phase'], pointgroup=system['pointgroup']) for temp in temperature_range(conditions): thermo.summary(temp) elif args.command == 'anharmonic': atoms = read_vasp_out('OUTCAR', index=-1) for temp in temperature_range(conditions): df6 = anharmonic_frequencies(atoms, temp, ) df4 = anharmonic_frequencies(atoms, temp, ) df = merge_vibs(df6, df4, temp) thermo = AnharmonicThermo(df, atoms, conditions, system) thermo.summary(temp)
if __name__ == '__main__': main()