def get_random_structure(elem, num_atom, sg, dim, thickness=0): max_try = 100 factor = 1.0 i = 0 while i < max_try: random.seed(time.time() * 1e8) if sg == 0: sg = get_random_spg(dim) symbol, sg = get_symbol_and_number(sg, dim) if dim == 3: rand_crystal = random_crystal(sg, elem, num_atom, factor) elif dim == 2: rand_crystal = random_crystal_2D(sg, elem, num_atom, thickness, factor) elif dim == 1: rand_crystal = random_crystal_1D(sg, elem, num_atom, thickness, factor) if dim == 0: rand_crystal = random_cluster(sg, elem, num_atom, factor) if rand_crystal.valid: comp = str(rand_crystal.struct.composition) comp = comp.replace(" ", "") if dim > 0: outpath = comp + '.cif' CifWriter(rand_crystal.struct, symprec=0.1).write_file(filename=outpath) ans = get_symmetry_dataset(rand_crystal.spg_struct, symprec=1e-1)['international'] print('Symmetry requested: {:d}({:s}), generated: {:s}'.format( sg, symbol, ans)) return True else: outpath = comp + '.xyz' rand_crystal.to_file(filename=outpath, fmt='xyz') ans = PointGroupAnalyzer(rand_crystal.molecule).sch_symbol print('Symmetry requested: {:d}({:s}), generated: {:s}'.format( sg, symbol, ans)) return True i += 1
def test_atomic_1D(): global outstructs global outstrings print( "=== Testing generation of atomic 1D crystals. This may take some time. ===" ) from time import time from spglib import get_symmetry_dataset from pyxtal.symmetry import get_rod from pyxtal.crystal import random_crystal_1D from pymatgen.symmetry.analyzer import SpacegroupAnalyzer slow = [] failed = [] print(" Rod group | Gen sg. (SPG) | Gen. sg (PMG) |Time Elapsed") skip = [] # slow to generate for num in range(1, 76): if num not in skip: multiplicity = len( get_rod(num)[0]) # multiplicity of the general position start = time() rand_crystal = random_crystal_1D(num, ["H"], [multiplicity], 4.0) end = time() timespent = np.around((end - start), decimals=2) t = str(timespent) if len(t) == 3: t += "0" t += " s" if timespent >= 1.0: t += " ~" if timespent >= 3.0: t += "~" if timespent >= 10.0: t += "~" if timespent >= 60.0: t += "~" slow.append(num) if rand_crystal.valid: try: ans1 = get_symmetry_dataset(rand_crystal.spg_struct, symprec=1e-1) except: ans1 = "???" if ans1 is None or ans1 == "???": ans1 = "???" else: ans1 = ans1["number"] sga = SpacegroupAnalyzer(rand_crystal.struct) try: ans2 = sga.get_space_group_number() except: ans2 = "???" if ans2 is None: ans2 = "???" check = True # output cif files for incorrect space groups if check is True: if check_struct_group(rand_crystal, num, dim=1): pass else: t += " xxxxx" outstructs.append(rand_crystal.struct) outstrings.append( str("1D_Atomic_" + str(num) + ".vasp")) print("\t" + str(num) + "\t|\t" + str(ans1) + "\t|\t" + str(ans2) + "\t|\t" + t) else: print("~~~~ Error: Could not generate layer group " + str(num) + " after " + t) failed.append(num) if slow != []: print( "~~~~ The following layer groups took more than 60 seconds to generate:" ) for i in slow: print(" " + str(i)) if failed != []: print("~~~~ The following layer groups failed to generate:") for i in failed: print(" " + str(i))
def from_random( self, dim=3, group=None, species=None, numIons=None, factor=1.1, thickness=None, area=None, lattice=None, sites=None, conventional=True, diag=False, t_factor=1.0, max_count=10, force_pass=False, ): if self.molecular: prototype = "molecular" else: prototype = "atomic" tm = Tol_matrix(prototype=prototype, factor=t_factor) count = 0 quit = False while True: count += 1 if self.molecular: if dim == 3: struc = molecular_crystal(group, species, numIons, factor, lattice=lattice, sites=sites, conventional=conventional, diag=diag, tm=tm) elif dim == 2: struc = molecular_crystal_2D(group, species, numIons, factor, thickness=thickness, sites=sites, conventional=conventional, tm=tm) elif dim == 1: struc = molecular_crystal_1D(group, species, numIons, factor, area=area, sites=sites, conventional=conventional, tm=tm) else: if dim == 3: struc = random_crystal(group, species, numIons, factor, lattice, sites, conventional, tm) elif dim == 2: struc = random_crystal_2D(group, species, numIons, factor, thickness, lattice, sites, conventional, tm) elif dim == 1: struc = random_crystal_1D(group, species, numIons, factor, area, lattice, sites, conventional, tm) else: struc = random_cluster(group, species, numIons, factor, lattice, sites, tm) if force_pass: quit = True break elif struc.valid: quit = True break if count >= max_count: raise RuntimeError( "It takes long time to generate the structure, check inputs" ) if quit: self.valid = struc.valid self.dim = dim try: self.lattice = struc.lattice if self.molecular: self.numMols = struc.numMols self.molecules = struc.molecules self.mol_sites = struc.mol_sites self.diag = struc.diag else: self.numIons = struc.numIons self.species = struc.species self.atom_sites = struc.atom_sites self.group = struc.group self.PBC = struc.PBC self.source = 'random' self.factor = struc.factor self.number = struc.number self._get_formula() except: pass
def test_mutiple_species(self): struc = random_crystal_1D(4, ["Mo", "S"], [2, 4], 1.0) self.assertTrue(struc.valid)
def test_single_specie(self): struc = random_crystal_1D(20, ["C"], [4], 1.0) struc.to_file() self.assertTrue(struc.valid)
outdir = options.outdir dimension = options.dimension thickness = options.thickness if not os.path.exists(outdir): os.mkdir(outdir) for i in range(attempts): numIons0 = np.array(numIons) start = time() if dimension == 3: rand_crystal = random_crystal(sg, system, numIons0, factor) elif dimension == 2: rand_crystal = random_crystal_2D(sg, system, numIons0, factor, thickness) elif dimension == 1: rand_crystal = random_crystal_1D(sg, system, numIons0, factor, thickness) if dimension == 0: rand_crystal = random_cluster(sg, system, numIons0, factor) end = time() timespent = np.around((end - start), decimals=2) if rand_crystal.valid: # Output a cif or xyz file pmg_struc = rand_crystal.to_pymatgen() ase_struc = rand_crystal.to_ase() comp = str(pmg_struc.composition) comp = comp.replace(" ", "") if dimension > 0: outpath = outdir + "/" + comp + ".cif" CifWriter(pmg_struc, symprec=0.1).write_file(filename=outpath) else: