WMD-group / SMACT

Python package to aid materials design and informatics
https://smact.readthedocs.io
MIT License
96 stars 21 forks source link

Some Boron Oxidation States Missing #278

Closed AnikenC closed 2 months ago

AnikenC commented 2 months ago

Hi!

I have noticed that several known compounds with Boron have been failing charge neutrality checks with smact, upon investigating further it seems that some oxidation states are missing for Boron. A simple fix would be to add the negative states which I believe should be (-5, -3, -2, -1)

## Boron Oxidation States

import smact
from pymatgen.core.composition import Composition

boron_compound = 'B2.0Mg1.0' # Magnesium Diboride
form_dict = Composition(boron_compound).to_reduced_dict
comp = tuple(form_dict.keys())
count = list(form_dict.values())

space = smact.element_dictionary(comp)
smact_elems = [e[1] for e in space.items()]
ox_states = [e.oxidation_states for e in smact_elems]

print(f"Elements: {comp}")
print(f"Oxidation States: {ox_states}") 
# Returns [[1, 2, 3], [1, 2]]
# However the valid combination for Boron is (-1, 2+), so smact.neutral_ratios returns false for this compound
aronwalsh commented 2 months ago

Thanks for raising this @AnikenC.

This summer, a student is working on introducing rules for intermetallics, which are not described well by oxidation states due to the nature of the chemical bonding and the polyatomic building blocks that often form.

For now, there is an alternative icsd-derived list that contains more B oxidation states, which you can switch to: smact/data/oxidation_states_icsd.txt

AntObi commented 2 months ago

Hi @AnikenC, As @aronwalsh has mentioned, there are a variety of oxidation state sets that are contained within smact, see the documentation (https://smact.readthedocs.io/en/stable/smact.html#smact.Element.oxidation_states).

For your particular example, this code snippet should show the different oxidation states:

## Boron Oxidation States

import smact
from pymatgen.core.composition import Composition

boron_compound = 'B2.0Mg1.0' # Magnesium Diboride
form_dict = Composition(boron_compound).to_reduced_dict
comp = tuple(form_dict.keys())
count = list(form_dict.values())

space = smact.element_dictionary(comp)
smact_elems = [e[1] for e in space.items()]
ox_states = [e.oxidation_states for e in smact_elems]

print(f"Elements: {comp}")

# These are the different types of oxidation states that can be returned from SMACT
ox_names = ["oxidation_states", "oxidation_states_icsd", "oxidation_states_sp",]

# Loop through the different types of oxidation states
for ox_names in ox_names:
    # Use getattr to get the attribute from the Element object
    ox_states=[getattr(e, ox_names) for e in smact_elems]
    # Print the oxidation states
    print(f"{ox_names.replace('_',' ').title()}: {ox_states}")

# Returns: 
# Oxidation States:  [[1, 2, 3], [1, 2]]
# Oxidation States Icsd: [[-3, -2, -1, 1, 2, 3], [2]]
# Oxidation States Sp: Oxidation States Sp: [[3], [2]]

It is also possible for a user to supply their own oxidation states file.