MaterSim / PyXtal

A code to generate atomic structure with symmetry
MIT License
246 stars 65 forks source link

Failed to use Tol_matrix #274

Open SmallBearC opened 2 days ago

SmallBearC commented 2 days ago

I have write a code : import os from ase.io import read,write import random from pyxtal import pyxtal from pyxtal.tolerance import Tol_matrix from pyxtal.lattice import Lattice

def parse_input_file(filename): params = {} with open(filename, 'r') as file: for line in file: line = line.strip() if not line or line.startswith('#'): continue key, value = line.split('=') key = key.strip() value = value.strip() if key == 'elements': params[key] = value.split(',') elif key == 'numbers': params[key] = [list(map(int, range_str.split('-'))) for range_str in value.split(',')] elif key in ['spg', 'num_structures']: params[key] = int(value) elif key in ['a', 'b', 'c', 'alpha', 'beta', 'gamma']: params[key] = float(value) else: params[key] = value return params

def generate_compositions(elements, numbers, current_composition=None, index=0): if current_composition is None: current_composition = []

if index == len(elements):
    yield dict(zip(elements, current_composition))
else:
    for num in range(numbers[index][0], numbers[index][1] + 1):
        yield from generate_compositions(elements, numbers, current_composition + [num], index + 1)

def main(): params = parse_input_file('com.inp') dim = int(params['dim']) elements = [e.strip() for e in params['elements']] numbers = params['numbers'] spg_upper = int(params['spg_upper']) num_structures = params['num_structures'] lattice_type = params['lattice_type'] a = params['a'] b = params['b'] c = params['c'] alpha = params['alpha'] beta = params['beta'] gamma = params['gamma']

cell = Lattice.from_para(a, b, c, alpha, beta, gamma, ltype=lattice_type)

**TM = Tol_matrix(prototype="metallic", factor=1.2)**

output_dir = "strus"
os.makedirs(output_dir, exist_ok=True)

n = 0
for composition in generate_compositions(elements, numbers):
    for i in range(num_structures):
        crystal = pyxtal()
        numbers = [composition[element] for element in elements]
        print(numbers)

        while True:
            spg = random.randint(1, spg_upper)
            try:
                crystal.from_random(dim,  
                                    spg,
                                    elements,  
                                    numbers,  
                                    **tm = TM**
                                    )
                break 
            except :
                print(f"Space group {spg} not compatible with composition {numbers}. Set to be 1")
                spg = 1
                continue  
        n += 1
        atoms = crystal.to_ase()
        atoms.set_cell([a, b, c])
        atoms.center()
        write(f"{output_dir}/{n}-POSCAR", atoms, format='vasp')

if name == "main": main()

I used the Tol_matrix class to control the smallest distance,but it failed. A lot of atoms with a distance smaller than 0.5. I get the same results without this class, that means the default smallest distance control also not work.

qzhu2017 commented 2 days ago

@SmallBearC Sorry, I cannot understand your code and problem description. Could you please come up with concise script and some results to explain your issue? Ideally, I want to see a small piece of code to run and reproduce your results.

Please also pay attention on the formatting with markdown while writing your issue.

SmallBearC commented 2 days ago

Thank you for your reply. I am very sorry that I provided the wrong code format. What's more, I rechecked my code and found that this is not a problem with PyXtal, but rather an incorrect use of ASE in my code. I am so sorry.