IdealGasThermo class that will get the job done. All you need is the optimized structure and the corresponding vibrational energies (i.e. a unit conversion from the frequencies). The theory behind this is described in ⚙️Ideal Gas Thermochemistry . There is also the GoodVibes code that includes some fancy features but is not yet compatible with MLIPs.QHACalc class in matcalc is included below. In practice, this is too expensive to do with DFT in most cases, and MLIPs can prove critical.pip install git+https://github.com/materialyzeai/matcalc.gitimport loggingfrom matcalc import QHACalcimport matplotlib.pyplot as pltfrom ase.io import read# Set logging levellogging.basicConfig(level=logging.INFO)# Read Atoms objectatoms = read("...")# Instantiate calculator as usualcalc = ...# Run QHA from 0 K to 600.0 K at 1 barresults = QHACalc(calc, pressure=1e-4, t_max=600.0, fmax=1e-6, optimizer="FIRE", max_steps=10000, scale_factors=(0.97, 0.98, 0.99, 1.0, 1.01, 1.02, 1.03), fix_imaginary_attempts=1).calc(atoms)# Fetch some resultsthermal_expansion = results["thermal_expansion_coefficients"]c_P = results["heat_capacity_P"]results["qha"].plot_qha()plt.savefig("qha.png")
QHACalc if you are allowing the unit cell shape to change, which is the default.fix_imaginary_attempts keyword argument that will automatically rattle the atoms and rerun the relaxation and phonon calculation for a specific volume if imaginary modes are detected. By setting it to 1, it means this correction will be attempted once. You may need to change this — read the logs. You may not be able to resolve all of the imaginary modes, but there should be relatively few and of low magnitude (again, check the logs). You should read this paper for an understanding of the impact that imaginary modes can have on the thermochemistry.