materialsproject / pymatgen

Python Materials Genomics (pymatgen) is a robust materials analysis code that defines classes for structures and molecules with support for many electronic structure codes. It powers the Materials Project.
https://pymatgen.org
Other
1.52k stars 867 forks source link

`MaterialsProject2020Compatibility` doesn't apply oxide/sulfide corrections if `O`/`S` have oxidation states #3185

Closed janosh closed 1 year ago

janosh commented 1 year ago

This minimal example of mp-18767 (LiMnO2) currently doesn't receive an oxide correction.

Expected corrections

Energy Adjustments: MP2020 anion correction (oxide): -2.7480 eV (-0.3435 eV/atom) MP2020 GGA/GGA+U mixing correction (Mn): -3.3360 eV (-0.4170 eV/atom)

Actual

Energy Adjustments: MP2020 GGA/GGA+U mixing correction (Mn): -3.3360 eV (-0.4170 eV/atom)

from pymatgen.core import Structure
from pymatgen.entries.compatibility import MaterialsProject2020Compatibility
from pymatgen.entries.computed_entries import ComputedStructureEntry

params = {
    "run_type": "GGA+U",
    "is_hubbard": True,
    "pseudo_potential": {
        "functional": "PBE",
        "labels": ["Li_sv", "O", "Mn_pv"],
        "pot_type": "paw",
    },
    "hubbards": {"Li": 0.0, "O": 0.0, "Mn": 3.9},
    "potcar_symbols": ["PBE Li_sv", "PBE O", "PBE Mn_pv"],
    "oxide_type": "oxide",
}

lmo = Structure.from_file("mp-18767-LiMnO2.cif")
cse = ComputedStructureEntry(lmo, -58.97, parameters=params)

MaterialsProject2020Compatibility().process_entry(cse, clean=True, on_error="raise")
None ComputedStructureEntry - Li2 Mn2 O4   (LiMnO2)
Energy (Uncorrected)     = -58.9700  eV (-7.3712  eV/atom)
Correction               = -3.3360   eV (-0.4170  eV/atom)
Energy (Final)           = -62.3060  eV (-7.7882  eV/atom)
Energy Adjustments:
  MP2020 GGA/GGA+U mixing correction (Mn): -3.3360   eV (-0.4170  eV/atom)
Parameters:
  run_type               = GGA+U
  is_hubbard             = True
  pseudo_potential       = {'functional': 'PBE', 'labels': ['Li_sv', 'O', 'Mn_pv'], 'pot_type': 'paw'}
  hubbards               = {'Li': 0.0, 'O': 0.0, 'Mn': 3.9}
  potcar_symbols         = ['PBE Li_sv', 'PBE O', 'PBE Mn_pv']
  oxide_type             = oxide
Data:
  oxidation_states       = {'Li': 1.0, 'Mn': 3.0, 'O': -2.0}
mp-18767-LiMnO2.cif ```cif # generated using pymatgen data_LiMnO2 _symmetry_space_group_name_H-M 'P 1' _cell_length_a 2.86877900 _cell_length_b 4.63447500 _cell_length_c 5.83250700 _cell_angle_alpha 90.00000000 _cell_angle_beta 90.00000000 _cell_angle_gamma 90.00000000 _symmetry_Int_Tables_number 1 _chemical_formula_structural LiMnO2 _chemical_formula_sum 'Li2 Mn2 O4' _cell_volume 77.54484024 _cell_formula_units_Z 2 loop_ _symmetry_equiv_pos_site_id _symmetry_equiv_pos_as_xyz 1 'x, y, z' loop_ _atom_type_symbol _atom_type_oxidation_number Li+ 1.0 Mn3+ 3.0 O2- -2.0 loop_ _atom_site_type_symbol _atom_site_label _atom_site_symmetry_multiplicity _atom_site_fract_x _atom_site_fract_y _atom_site_fract_z _atom_site_occupancy Li+ Li0 1 0.50000000 0.50000000 0.37975050 1 Li+ Li1 1 0.00000000 0.00000000 0.62024950 1 Mn3+ Mn2 1 0.50000000 0.50000000 0.86325250 1 Mn3+ Mn3 1 0.00000000 0.00000000 0.13674750 1 O2- O4 1 0.50000000 0.00000000 0.36082450 1 O2- O5 1 0.00000000 0.50000000 0.09851350 1 O2- O6 1 0.50000000 0.00000000 0.90148650 1 O2- O7 1 0.00000000 0.50000000 0.63917550 1 ```
janosh commented 1 year ago

The problem is on this line which uses Composition.__contains__ to check for oxygen in the entry composition. Composition doesn't currently contain an Element if that Element appears as a Species with an oxidation state.

https://github.com/materialsproject/pymatgen/blob/5c5f271ad1d6ca2e51146db4d61df99960d5acac/pymatgen/entries/compatibility.py#L280-L281