WMD-group / SMACT

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

Multi Valence charge balancing #267

Open CompRhys opened 4 days ago

CompRhys commented 4 days ago

I was thinking about how one might implement a multivalent charge balancing scheme and wondered whether there was any work in SMACT on adding this and what state that effort might be in.

The canonical example here would be something like iron oxide

from smact.screening import smact_validity
from pymatgen.core import Composition

print(f"{smact_validity(Composition('Fe3O4'))=}")
print(f"{smact_validity(Composition('Fe2O3'))=}")
print(f"{smact_validity(Composition('FeO'))=}")
smact_validity(Composition('Fe3O4'))=False
smact_validity(Composition('Fe2O3'))=True
smact_validity(Composition('FeO'))=True
AntObi commented 4 days ago

Hi @CompRhys , handling mixed valency is an ongoing development goal for us (see the related discussion #196 ). We currently are working towards updating the smact_validity function to enable the consideration of mixed valence compounds. Our current thought process for the example of Fe3O4 would be to consider 3 Fe atoms and enumerate the possible oxidation states they could adopt in order to charge balance the 4 O2- ions. This would lead to one possible solution of having 2 Fe3+ ions and 1 Fe2+ which would solve the charge balance problem.

The main idea now is to work on an efficient implementation of this idea that would work for any possible mixed valence compound. We would not have this be the default behaviour of the smact_validity function, but be an optional routine that only runs when an optional argument is set to True.

I hope that sufficiently describes our ongoing approach to the mixed valency problem.

Tagging @aronwalsh @hspark1212 @keeeto as this issue will also be of interest to all of you!

aronwalsh commented 4 days ago

Thanks for flagging this @CompRhys and @AntObi for responding. We have a couple of summer projects related to extending the rules, which will include finalising this issue. Of course, if you have other solutions in mind, feel free to share.

For smact_validity(), it should be straightforward. For counting purposes, curiously Fe3O4 is binary in terms of elements, but ternary in terms of species.

CompRhys commented 3 days ago

The only line of thought I have is that if you do allow multiple valencies then you have to frame it as a constrained integer program over a much larger set of species that can exist simultaneously, you then need to put constraints on the optimizer to ensure the stoichiometry is correct. That seems fairly straightforward to do but I have given less thought to the additional filters implemented here and whether they fit into that linear constraint framework that we could do with something like scipy.optimize.mlip. If we can't have them as constraints then we need to find all valid solutions to the optimization as it's entirely reasonable that there could be many assignments that work but that most would not pass these additional filters.

CompRhys commented 3 days ago

In terms of finding all valid solutions the naive approach seems to be that you would do it in a loop until failure where after each successful iteration you add a constraint that the new solutions must be different. The problem is that this seems likely to be extremely slow compared to current implementation and so if you wanted to consider the same all quaternaries of reasonable elements up then how much would the runtime jump? currently it's minutes, would it become days or weeks?