pymatgen
pymatgen copied to clipboard
Generate random ordered structures from disordered structure
Problem
For molecular dynamics simulation and machine learning data generation of random structures, one might desire to have a routine that transforms a given disordered structure $S$ to a set of randomly ordered structures $\{S'_i\}$, where each randomly ordered structure $S'_i$ has the same overall composition as the disordered structure $S$.
Currently for this purpose, there exists OrderDisorderedStructureTransformation
in transformations/standard_transformations.py
. However, this function over-complicates the problem by using the Ewald energy to rank the generated randomly ordered structures. When the structure in question is very large (e.g. >= thousands of atoms in a typical MD simulation), this approach simply won't work due to the combinatorially increasing search space. Instead, what we actually want is very simple: a set of randomly ordered structures. The energy ranking is not of concern here.
Proposed Solution
We have implemented a new standard transformation routine, named RandomStructureTransformation
. Given a disordered structure
, and a number num_copies
, its method apply_transformation
returns a set of num_copies
copies of randomly ordered structures. This routine distinguishes between inequivalent sublattices of the crystal.
Additional Info
The following example shows the usage of this routine:
from mp_api.client import MPRester
from pymatgen.transformations.standard_transformations \
import RandomStructureTransformation
# put your api_key here
api_key = "*****"
with MPRester(api_key) as mpr:
struct = mpr.get_structure_by_material_id("mp-2534", conventional_unit_cell=True) # GaAs
struct[0:4] = {"Ga": 0.5, "In": 0.5}
struct[4:] = {"P": 0.5, "As": 0.5}
struct.make_supercell([3, 3, 3])
# random structure transformation
trans = RandomStructureTransformation()
new_structs = trans.apply_transformation(structure = struct,
num_copies = 5)
# save structures to files
for i_struct, new_struct in enumerate(new_structs):
new_struct.to("random_structure_{}.cif".format(i_struct))
Below are the screenshots of the generated random structures:
If this feature is desired, I can initiate a pull request.
Could you share how this differs from EnumerateStructureTransformation
backed by enumlib
?
Also, thank you for the clearly described and illustrated issue.
Hi @mkhorton, thank you very much for your comment! I just found out about EnumerateStructureTransformation
. Upon checking the documentation, it seems that this transformation requires enumlib
and some other arguments (I'm not quite familiar with what these arguments do). It seems also that EnumerateStructureTransformation
has some kind of ordering using either Ewald or M3GNet energy. These features are not present in RandomStructureTransformation
, but it uses random.shuffle
to randomly assign site elements. Does this answer your question somewhat?
hello, exenGT, I'm wondering how did you show the crystal strucuture in this Issue, please inform me, thank you very much !!!
Hi @HegemonyTao, sorry for my late reply. The crystal structures here are visualized with VESTA. Hope that helps!