Error in the formation enthalpies?

Dear All,

i checked the formation enthalpies for some compounds and calculated them with own VASP calculations for validation.

I downloaded the MPrelaxset for mp-2317: LaNi5 (Hexagonal, P6/mmm, 191) and my result was exactly the same: -0.282eV/atom.

For this compound: mp-23671: LaNi5H7 (Hexagonal, P6_3mc, 186) the result -0.319eV/atom is way of, off the calcualted value with the MPrelax set (-0.224eV/atom).

Details. I calculated the reference pure elements of the given elements in the edges of the phase diagram (Ni: mp-23; H2: mp-730101; La: mp-26)

The formation enthalpies get calculated by the total energy of the compound minus the amount of pure elements in the POSCAR file. Then divided by the number of atoms in the compound.
What could be the reason?

Thank you, Peter.

Hi @Petthebat,

The difference you’re seeing is dependent on the DFT functional used for each calculation, as well as the mixing / correction scheme used by MP.

For example, the MPRelaxSet uses either PBE or PBE+U, whereas the MPScanRelaxSet uses r2SCAN. MP is currently transitioning all of its calculations to the more accurate r2SCAN functional.

In addition to this, MP applies corrections for compatibilities and known deficits of DFT to formation energies. That shifts the computed formation enthalpy away from the raw DFT value.

To see this, let’s pull the same materials you identified from MP using the API:

from mp_api.client import MPRester

mpids = ["mp-2317","mp-23671","mp-23","mp-730101","mp-26"]
elemental_to_mpid = {"Ni": "mp-23", "H": "mp-730101", "La": "mp-26"}

with MPRester() as mpr:
    thermo_docs =

corrected_formation_enthalpies = {
    mpid: {} for mpid in mpids if mpid not in elemental_to_mpid.values()
for doc in thermo_docs:
    if (mpid := str(doc.material_id)) in corrected_formation_enthalpies:
        corrected_formation_enthalpies[mpid][str(doc.thermo_type)] = doc.formation_energy_per_atom

If you print corrected_formation_enthalpies, you should get something like this:

{'mp-2317': {'GGA_GGA+U': -0.2817098874999999,
  'R2SCAN': -0.24004932416666472,
  'GGA_GGA+U_R2SCAN': -0.2817098875000011},
 'mp-23671': {'R2SCAN': -0.24349168432692198,
  'GGA_GGA+U': -0.32070788961538454,
  'GGA_GGA+U_R2SCAN': -0.3193938314423089}}

which lines up with what you see on the website, when you look at the GGA_GGA+U_R2SCAN keys. This is currently the preferred method for MP, and reflects our most up-to-date corrected DFT methods.

If we instead try to get the uncorrected/raw formation energies from MP, we need a little more manipulation:

energies_per_atom = {mpid: {} for mpid in mpids}
compositions = {}
for doc in thermo_docs:
    mpid = str(doc.material_id)
    energies_per_atom[mpid][str(doc.thermo_type)] = doc.uncorrected_energy_per_atom
    if mpid not in compositions:
        compositions[mpid] = doc.composition.as_dict()

formation_energies = {
    mpid : {
        dfa : energy_per_atom
        for dfa, energy_per_atom in entry.items()
    } for mpid, entry in energies_per_atom.items() if mpid not in elemental_to_mpid.values()
for mpid, entry in formation_energies.items():
    for dfa in entry:
        formation_energies[mpid][dfa] -= sum(
            stoich * energies_per_atom[elemental_to_mpid[atom]][dfa]
            for atom, stoich in compositions[mpid].items()

But printing formation_energies gives about the same values you found with the MPRelaxSet when you look at the GGA_GGA+U key:

{'mp-2317': {'GGA_GGA+U': -0.2817098874999999,
  'R2SCAN': -0.2400493241666659,
  'GGA_GGA+U_R2SCAN': -0.2400493241666659},
 'mp-23671': {'R2SCAN': -0.24349168432692103,
  'GGA_GGA+U': -0.2266397552884607,
  'GGA_GGA+U_R2SCAN': -0.24349168432692103}}