pwtools.thermo.HarmonicThermo

class pwtools.thermo.HarmonicThermo(freq, dos, T=None, temp=None, skipfreq=False, eps=3.3306690738754696e-16, fixnan=False, nanfill=0.0, dosarea=None, integrator=<function trapz>, verbose=True)[source]

Bases: object

Calculate vibrational internal energy (Evib [eV]), free energy (Fvib [eV]), entropy (Svib [R,kb]) and isochoric heat capacity (Cv [R,kb]) in the harmonic approximation from a phonon density of states.

__init__(freq, dos, T=None, temp=None, skipfreq=False, eps=3.3306690738754696e-16, fixnan=False, nanfill=0.0, dosarea=None, integrator=<function trapz>, verbose=True)[source]
Parameters:
  • freq (1d array) – frequency f (NOT 2*pi*f) [cm^-1]

  • dos (1d array) – phonon dos such that int(freq) dos = 3*natom

  • T (1d array, optional) – temperature range [K], if not given in the constructor then use temp in the calculation methods

  • skipfreq (bool, optional) – Ignore frequencies and DOS values where the frequencies are negative or close to zero, i.e. all DOS curve values where freq < eps. The number and rms of the skipped values is printed if verbose=True.

  • eps (float, optional) – Threshold for skipfreq. Default is ~1.5*2.2e-16 .

  • fixnan (bool, optional) – Use if YKWYAD, test before using! Currently, set all NaNs occurring during integration to nanfill. This is a HACK b/c we must assume that these numbers should be nanfill.

  • nanfill (float, optional) – During integration over temperature, set NaNs to this value.

  • dosarea (float or None) – If not None, then re-normalize the area int(freq) dos to dosarea, after skipfreq was applied if used.

  • integrator (callable) – Function which integrates x-y data. Called as integrator(y,x), like scipy.integrate.{trapz,simps}. Usually, trapz is numerically more stable for weird DOS data and accurate enough if the frequency axis resolution is good.

  • verbose (bool, optional) – Print warnings. Recommended for testing.

Notes

skipfreq and fixnan: Sometimes, a few frequencies (usually the 1st few values only) are close to zero and negative, and the DOS is very small there. skipfreq can be used to ignore this region. The default is False b/c it may hide large negative frequencies (i.e. unstable structure), which is a perfectly valid result (but you shouldn’t do thermodynamics with that :) Even if there are no negative frequencies, you can have frequencies (usually the first) being exactly zero or close to that (order 1e-17). That can cause numerical problems (NaNs) in some calculations so we may skip them and their DOS values, which must be assumed to be small. If you still encounter NaNs during integration, you may use fixnan to set them to nanfill. But that is a hack. If you cannot get rid of NaNs by skipfreq, then your freq-dos data is probably fishy!

Methods

cv(*args, **kwargs)

Same as isochoric_heat_capacity().

evib(*args, **kwargs)

Same as vibrational_internal_energy().

fvib(*args, **kwargs)

Same as vibrational_free_energy().

isochoric_heat_capacity([temp])

Cv [R, kb]

svib(*args, **kwargs)

Same as vibrational_entropy().

vibrational_entropy([temp])

Svib [R, kb]

vibrational_free_energy([temp])

Fvib [eV]

vibrational_internal_energy([temp])

Evib [eV]