def test_preassigned_sites(self): sites = [["1b"], ["1b"], ["2c", "1b"]] struc = random_crystal(99, ["Ba", "Ti", "O"], [1, 1, 3], 1.0, sites=sites) self.assertTrue(struc.valid) struc = random_crystal(225, ["C"], [3], 1.0, sites=[["4a", "8c"]]) self.assertTrue(struc.valid)
def _try(formula: str, sg: int, elements: List[str], stois: Union[List[int], np.ndarray], lattice: Lattice, vf: float): try: # logging.debug( f"{formula} {sg} {elements} {stois} {lattice} {vf}") crystal = random_crystal(sg, elements, stois, vf, lattice=lattice) logging.debug(f"_try Is crystal valid {is_valid_crystal(crystal)}") except Exception as e: logging.error( f"During random crystal generation: \n {formula} {sg} {elements} {stois} \n Error Message: {e}" ) crystal = None finally: return crystal
def test_cubic_cubic(self): sites = ['8a', '32e'] G, fac = 227, 4 numIons = int(sum([int(i[:-1]) for i in sites]) / fac) while True: C1 = random_crystal(G, ['C'], [numIons], sites=[sites]) if C1.valid: break pmg_s1 = C1.to_pymatgen() sga1 = SpacegroupAnalyzer(pmg_s1).get_space_group_symbol() C2s = C1.subgroup() for C2 in C2s: pmg_s2 = C2.to_pymatgen() sga2 = SpacegroupAnalyzer(pmg_s2).get_space_group_symbol() self.assertTrue(sm.StructureMatcher().fit(pmg_s1, pmg_s2))
def test_from_seed(self): from pymatgen import Lattice, Structure coords = [[0, 0, 0], [0.75, 0.5, 0.75]] lattice = Lattice.from_parameters(a=3.84, b=3.84, c=3.84, alpha=120, beta=90, gamma=60) struct = Structure(lattice, ["Si", "C"], coords) s1 = random_crystal(seed=struct) s2 = s1.subgroup(once=True) pmg_s1 = s1.to_pymatgen() pmg_s2 = s2.to_pymatgen() #sga1 = SpacegroupAnalyzer(pmg_s1).get_space_group_symbol() #sga2 = SpacegroupAnalyzer(pmg_s2).get_space_group_symbol() self.assertTrue(sm.StructureMatcher().fit(pmg_s1, pmg_s2))
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 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
time_total = 0 for opt in optimizations: struc, energy, time, error = single_optimize(struc, ff, opt, exe, path, label) time_total += time if error: return None, 100000, 0, True return struc, energy, time_total, False if __name__ == "__main__": from pyxtal.crystal import random_crystal while True: count = 0 struc = random_crystal(19, ["C"], [16], 1.0) if struc.valid: break calc = GULP(struc, opt="single", ff="tersoff.lib") calc.run() #calc.clean_up = False print(calc.energy) print(calc.stress) print(calc.forces) struc, eng, time, _ = optimize(struc.to_ase(), ff="tersoff.lib") print(struc) print(eng) print(time)
import pymatgen.analysis.structure_matcher as sm from pymatgen.symmetry.analyzer import SpacegroupAnalyzer import numpy as np from pyxtal.lattice import cellsize for G in range(1, 231): #for G in [90, 99, 105, 107, 203, 210, 224, 226, 227, 228]: g = Group(G) subs = g.get_max_t_subgroup() indices = subs['index'] hs = subs['subgroup'] relations = subs['relations'] tran = subs['transformation'] letter = str(g[0].multiplicity) + g[0].letter print(G) C1 = random_crystal(G, ['C'], [int(g[0].multiplicity / cellsize(g))], sites=[[letter]]) pmg_s1 = C1.to_pymatgen() sga1 = SpacegroupAnalyzer(pmg_s1).get_space_group_symbol() # each subgroup for i in range(len(relations)): C2 = C1.subgroup(eps=0, idx=[i], once=True) pmg_s2 = C2.to_pymatgen() try: sga2 = SpacegroupAnalyzer(pmg_s2, symprec=1e-4).get_space_group_symbol() except: #print("unable to find the space group") sga2 = None print(G, hs[i], g.symbol, sga1, Group(hs[i]).symbol, sga2, i) if not sm.StructureMatcher().fit(pmg_s1, pmg_s2): print('WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW')
from pyxtal.interface.gulp import GULP from pyxtal.crystal import random_crystal from ase import Atoms import os from spglib import get_symmetry_dataset file = "C-POSCARs" if os.path.exists(file): os.remove(file) for i in range(10): #struc = random_crystal(194, ["C"], [4], 1.0) struc = random_crystal(227, ["C"], [2], 1.0) if struc.valid: calc = GULP(struc, ff="tersoff.lib") calc.run() s = Atoms(calc.sites, scaled_positions=calc.positions, cell=calc.cell) info = get_symmetry_dataset(s, symprec=1e-1) s.write("1.vasp", format='vasp', vasp5=True, direct=True) os.system("cat 1.vasp >> " + file) print("{:4d} {:8.3f} {:s}".format(i, calc.energy / 8, info['international'])) #print(calc.stress) #print(calc.cell)
def generator(args): elements = args['elements'] composition = args['composition'] spg = args['spg'] wyckoff_position = args['wyckoff_position'] generation_info = args['generation_information'] cs = crystal.random_crystal(int(spg), species=elements, numIons=composition, factor=1) if not cs.valid: return None if wyckoff_position in list( np.unique([ '%d%s' % (s.wp.multiplicity, s.wp.letter) for s in cs.wyckoff_sites ])): cell = cs.struct.lattice.matrix reduced = cs.struct.frac_coords symbols = [ele.value for ele in cs.struct.species] structure = pychemia.Structure(cell=cell, symbols=symbols, reduced=reduced) sym = pychemia.crystal.CrystalSymmetry(structure) properties = { 'pretty_formula': structure.get_composition().sorted_formula(sortby='electroneg'), 'elements': elements, 'generation_information': generation_info, 'requested_spg': spg, 'spacegroup': { 'number': sym.number(symprec=1e-3), 'symbol': sym.symbol(symprec=1e-3), 'spglib_wyckoffs': sym.get_symmetry_dataset()['wyckoffs'], 'wyckoffs': list( np.unique([ '%d%s' % (s.wp.multiplicity, s.wp.letter) for s in cs.wyckoff_sites ])), } } print( str(properties['spacegroup']['number']) + '-' + str(structure.nspecies) + '-' + properties['pretty_formula'] + '.vasp') if spg != sym.number(symprec=1e-3): print('++++++++++++++++++++++++++++++++++++++++++++') print('++++++++++++++++++++++++++++++++++++++++++++') print( 'The requested space group %d not equal to the generated space group %d' % (spg, sym.number(symprec=1e-3))) cs.print_all() print(cs.frac_coords.round(5)) print(structure.reduced) print("--------------------------------------------") print('elements', elements) print('compisotion', composition) print('spg', spg) return None return (structure, properties)
def test_single_specie(self): struc = random_crystal(225, ["C"], [4], 1.2) struc.to_file() self.assertTrue(struc.valid)
def test_modules(): print("====== Testing functionality for pyXtal version 0.1dev ======") global failed_package failed_package = False # Record if errors occur at any level reset() print("Importing sys...") try: import sys print("Success!") except Exception as e: fail(e) sys.exit(0) print("Importing numpy...") try: import numpy as np print("Success!") except Exception as e: fail(e) sys.exit(0) I = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) print("Importing pymatgen...") try: import pymatgen print("Success!") except Exception as e: fail(e) sys.exit(0) try: from pymatgen.core.operations import SymmOp except Exception as e: fail(e) sys.exit(0) print("Importing pandas...") try: import pandas print("Success!") except Exception as e: fail(e) sys.exit(0) print("Importing spglib...") try: import spglib print("Success!") except Exception as e: fail(e) sys.exit(0) print("Importing openbabel...") try: import ase print("Success!") except: print( "Error: could not import openbabel. Try reinstalling the package.") print("Importing pyxtal...") try: import pyxtal print("Success!") except Exception as e: fail(e) sys.exit(0) print("=== Testing modules ===") # =====database.element===== print("pyxtal.database.element") reset() try: import pyxtal.database.element except Exception as e: fail(e) print(" class Element") try: from pyxtal.database.element import Element except Exception as e: fail(e) if passed(): for i in range(1, 95): if passed(): try: ele = Element(i) except: fail("Could not access Element # " + str(i)) try: y = ele.sf y = ele.z y = ele.short_name y = ele.long_name y = ele.valence y = ele.valence_electrons y = ele.covalent_radius y = ele.vdw_radius y = ele.get_all(0) except: fail("Could not access attribute for element # " + str(i)) try: ele.all_z() ele.all_short_names() ele.all_long_names() ele.all_valences() ele.all_valence_electrons() ele.all_covalent_radii() ele.all_vdw_radii() except: fail("Could not access class methods") check() # =====database.hall===== print("pyxtal.database.hall") reset() try: import pyxtal.database.hall except Exception as e: fail(e) print(" hall_from_hm") try: from pyxtal.database.hall import hall_from_hm except Exception as e: fail(e) if passed(): for i in range(1, 230): if passed(): try: hall_from_hm(i) except: fail("Could not access hm # " + str(i)) check() # =====database.collection===== print("pyxtal.database.collection") reset() try: import pyxtal.database.collection except Exception as e: fail(e) print(" Collection") try: from pyxtal.database.collection import Collection except Exception as e: fail(e) if passed(): for i in range(1, 230): if passed(): try: molecule_collection = Collection("molecules") except: fail("Could not access hm # " + str(i)) check() # =====operations===== print("pyxtal.operations") reset() try: import pyxtal.operations except Exception as e: fail(e) print(" random_vector") try: from pyxtal.operations import random_vector except Exception as e: fail(e) if passed(): try: for i in range(10): random_vector() except Exception as e: fail(e) check() print(" angle") try: from pyxtal.operations import angle except Exception as e: fail(e) if passed(): try: for i in range(10): v1 = random_vector() v2 = random_vector() angle(v1, v2) except Exception as e: fail(e) check() print(" random_shear_matrix") try: from pyxtal.operations import random_shear_matrix except Exception as e: fail(e) if passed(): try: for i in range(10): random_shear_matrix() except Exception as e: fail(e) check() print(" is_orthogonal") try: from pyxtal.operations import is_orthogonal except Exception as e: fail(e) if passed(): try: a = is_orthogonal([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) b = is_orthogonal([[0, 0, 1], [1, 0, 0], [1, 0, 0]]) if a is True and b is False: pass else: fail() except Exception as e: fail(e) check() print(" aa2matrix") try: from pyxtal.operations import aa2matrix except Exception as e: fail(e) if passed(): try: for i in range(10): aa2matrix(1, 1, random=True) except Exception as e: fail(e) check() print(" matrix2aa") try: from pyxtal.operations import matrix2aa except Exception as e: fail(e) if passed(): try: for i in range(10): m = aa2matrix(1, 1, random=True) aa = matrix2aa(m) except Exception as e: fail(e) check() print(" rotate_vector") try: from pyxtal.operations import rotate_vector except Exception as e: fail(e) if passed(): try: for i in range(10): v1 = random_vector() v2 = random_vector() rotate_vector(v1, v2) except Exception as e: fail(e) check() print(" are_equal") try: from pyxtal.operations import are_equal except Exception as e: fail(e) if passed(): try: op1 = SymmOp.from_xyz_string("x,y,z") op2 = SymmOp.from_xyz_string("x,y,z+1") a = are_equal(op1, op2, PBC=[0, 0, 1]) b = are_equal(op1, op2, PBC=[1, 0, 0]) if a is True and b is False: pass else: fail() except Exception as e: fail(e) check() print(" class OperationAnalyzer") try: from pyxtal.operations import OperationAnalyzer except Exception as e: fail(e) if passed(): try: for i in range(10): m = aa2matrix(1, 1, random=True) t = random_vector() op1 = SymmOp.from_rotation_and_translation(m, t) OperationAnalyzer(op1) except Exception as e: fail(e) check() print(" class Orientation") try: from pyxtal.operations import Orientation except Exception as e: fail(e) if passed(): try: for i in range(10): v1 = random_vector() c1 = random_vector() o = Orientation.from_constraint(v1, c1) except Exception as e: fail(e) check() # =====symmetry===== print("pyxtal.symmetry") reset() try: import pyxtal.symmetry except Exception as e: fail(e) print(" get_wyckoffs (may take a moment)") try: from pyxtal.symmetry import get_wyckoffs except Exception as e: fail(e) if passed(): try: for i in [1, 2, 229, 230]: get_wyckoffs(i) get_wyckoffs(i, organized=True) except: fail(" Could not access Wyckoff positions for space group # " + str(i)) check() print(" get_wyckoff_symmetry (may take a moment)") try: from pyxtal.symmetry import get_wyckoff_symmetry except Exception as e: fail(e) if passed(): try: for i in [1, 2, 229, 230]: get_wyckoff_symmetry(i) get_wyckoff_symmetry(i, molecular=True) except: fail("Could not access Wyckoff symmetry for space group # " + str(i)) check() print(" get_wyckoffs_generators (may take a moment)") try: from pyxtal.symmetry import get_wyckoff_generators except Exception as e: fail(e) if passed(): try: for i in [1, 2, 229, 230]: get_wyckoff_generators(i) except: fail("Could not access Wyckoff generators for space group # " + str(i)) check() print(" letter_from_index") try: from pyxtal.symmetry import letter_from_index except Exception as e: fail(e) if passed(): try: if letter_from_index(0, get_wyckoffs(47)) == "A": pass else: fail() except Exception as e: fail(e) check() print(" index_from_letter") try: from pyxtal.symmetry import index_from_letter except Exception as e: fail(e) if passed(): try: if index_from_letter("A", get_wyckoffs(47)) == 0: pass else: fail() except Exception as e: fail(e) check() print(" jk_from_i") try: from pyxtal.symmetry import jk_from_i except Exception as e: fail(e) if passed(): try: w = get_wyckoffs(2, organized=True) j, k = jk_from_i(1, w) if j == 1 and k == 0: pass else: print(j, k) fail() except Exception as e: fail(e) check() print(" i_from_jk") try: from pyxtal.symmetry import i_from_jk except Exception as e: fail(e) if passed(): try: w = get_wyckoffs(2, organized=True) j, k = jk_from_i(1, w) i = i_from_jk(j, k, w) if i == 1: pass else: print(j, k) fail() except Exception as e: fail(e) check() print(" ss_string_from_ops") try: from pyxtal.symmetry import ss_string_from_ops except Exception as e: fail(e) if passed(): try: strings = ["1", "4 . .", "2 3 ."] for i, sg in enumerate([1, 75, 195]): ops = get_wyckoffs(sg)[0] ss_string_from_ops(ops, sg, dim=3) except Exception as e: fail(e) check() print(" Wyckoff_position") try: from pyxtal.symmetry import Wyckoff_position except Exception as e: fail(e) if passed(): try: wp = Wyckoff_position.from_group_and_index(20, 1) except Exception as e: fail(e) check() print(" Group") try: from pyxtal.symmetry import Group except Exception as e: fail(e) if passed(): try: g3 = Group(230) g2 = Group(80, dim=2) g1 = Group(75, dim=1) except Exception as e: fail(e) check() # =====crystal===== print("pyxtal.crystal") reset() try: import pyxtal.crystal except Exception as e: fail(e) print(" random_crystal") try: from pyxtal.crystal import random_crystal except Exception as e: fail(e) if passed(): try: c = random_crystal(1, ["H"], [1], 10.0) if c.valid is True: pass else: fail() except Exception as e: fail(e) check() print(" random_crystal_2D") try: from pyxtal.crystal import random_crystal_2D except Exception as e: fail(e) if passed(): try: c = random_crystal_2D(1, ["H"], [1], 10.0) if c.valid is True: pass else: fail() except Exception as e: fail(e) check() # =====molecule===== print("pyxtal.molecule") reset() try: import pyxtal.molecule except Exception as e: fail(e) check() print(" Collections") try: from pyxtal.molecule import mol_from_collection except Exception as e: fail(e) if passed(): try: h2o = mol_from_collection("H2O") ch4 = mol_from_collection("CH4") except Exception as e: fail(e) print(" get_inertia_tensor") try: from pyxtal.molecule import get_inertia_tensor except Exception as e: fail(e) if passed(): try: get_inertia_tensor(h2o) get_inertia_tensor(ch4) except Exception as e: fail(e) check() print(" get_moment_of_inertia") try: from pyxtal.molecule import get_moment_of_inertia except Exception as e: fail(e) if passed(): try: v = random_vector() get_moment_of_inertia(h2o, v) get_moment_of_inertia(ch4, v) except Exception as e: fail(e) check() print(" reoriented_molecule") try: from pyxtal.molecule import reoriented_molecule except Exception as e: fail(e) if passed(): try: reoriented_molecule(h2o) reoriented_molecule(ch4) except Exception as e: fail(e) check() print(" orientation_in_wyckoff_position") try: from pyxtal.molecule import orientation_in_wyckoff_position except Exception as e: fail(e) if passed(): try: w = get_wyckoffs(20) ws = get_wyckoff_symmetry(20, molecular=True) wp = Wyckoff_position.from_group_and_index(20, 1) orientation_in_wyckoff_position(h2o, wp) orientation_in_wyckoff_position(ch4, wp) except Exception as e: fail(e) check() # =====molecular_crystal===== print("pyxtal.molecular_crystal") reset() try: import pyxtal.crystal except Exception as e: fail(e) print(" molecular_crystal") try: from pyxtal.molecular_crystal import molecular_crystal except Exception as e: fail(e) if passed(): try: c = molecular_crystal(1, ["H2O"], [1], 10.0) if c.valid is True: pass else: fail() except Exception as e: fail(e) check() print(" molecular_crystal_2D") try: from pyxtal.molecular_crystal import molecular_crystal_2D except Exception as e: fail(e) if passed(): try: c = molecular_crystal_2D(1, ["H2O"], [1], 10.0) if c.valid is True: pass else: fail() except Exception as e: fail(e) check() end(condition=2)
for index in inices: m2[index] = value elif len(indices) == 3: total = 0 for index in indices: total += stress[index] value = np.cbrt(total) for index in inices: m2[index] = value return m2 from pyxtal.crystal import random_crystal from spglib import get_symmetry_dataset for i in range(10): crystal = random_crystal(11, ['C'], [4], 1.0) if crystal.valid: crystal1 = deepcopy(crystal) test = LJ(epsilon=0.01, sigma=3.40, rcut=8.0) struc = (crystal1.lattice_matrix, crystal1.frac_coords, [6]*4) eng, enth, force, stress = test.calc(crystal1) sg = get_symmetry_dataset(struc)['number'] print('\nBefore relaxation Space group: {:4d} Energy: {:12.4} Enthalpy: {:12.4}'.format(sg, eng, enth)) dyn1 = FIRE(crystal1, test, f_tol=1e-5, dt=0.2, maxmove=0.2) #, symmetrize=True) dyn1.run(500) eng, enth, force, stress = test.calc(crystal1) struc = (dyn1.struc.lattice_matrix, dyn1.struc.frac_coords, [6]*4) sg = get_symmetry_dataset(struc, symprec=0.1)['number'] print('After relaxation without symm Space group: {:4d} Energy: {:12.4} Enthalpy: {:12.4}'.format(sg, eng, enth))
if __name__ == "__main__": from pyxtal.crystal import random_crystal from pyxtal.operations import apply_ops from ase import Atoms import pymatgen.analysis.structure_matcher as sm from spglib import get_symmetry_dataset from pymatgen.io.ase import AseAtomsAdaptor #sites = ['24f','6b'] #G, H, fac = 197, 23, 2 sites = ['32e'] #sites = ['8a'] G, H, fac = 227, 166, 4 numIons = int(sum([int(i[:-1]) for i in sites]) / fac) C = random_crystal(G, ['C'], [numIons], sites=[sites]) spg1 = get_symmetry_dataset(C.to_ase(), symprec=1e-4)['international'] splitter = wyckoff_split(G=G, H=H, wp1=sites) print(splitter) lat1 = np.dot(C.lattice.matrix, splitter.R[:3, :3].T) pos1 = None for i, site in enumerate(C.atom_sites): pos = site.position for ops1, ops2 in zip(splitter.G2_orbits[i], splitter.H_orbits[i]): pos0 = pos + 0.05 * (np.random.sample(3) - 0.5) #print(pos0) pos_tmp = apply_ops(pos0, ops1) pos_tmp = apply_ops(pos_tmp[0], ops2) if pos1 is None: pos1 = pos_tmp
coords = [] for ms in mol_sites: coords1, species1 = ms.get_coords_and_species() species += species1 for c in coords1: coords.append(c) coords = np.array(coords) Structure.__init__(self, lattice.matrix, species, coords) @classmethod def from_molecular_crystal(self, mc): """ Initialize from a molecular_crystal object """ if mc.valid: return Mstruct(mc.mol_generators, mc.lattice, mc.group) else: return None if __name__ == "__main__": from pyxtal.crystal import random_crystal c = random_crystal(225, ['C'], [4], 1) x = Xstruct.from_random_crystal(c) print(x.group) from pyxtal.molecular_crystal import molecular_crystal m = molecular_crystal(20, ['H2O'], [8], 1) x = Mstruct.from_molecular_crystal(m) print(x.group)
def test_mutiple_species(self): struc = random_crystal(99, ["Ba", "Ti", "O"], [1, 1, 3], 1.2) self.assertTrue(struc.valid)
def test_atomic(): global outstructs global outstrings print( "=== Testing generation of atomic 3D crystals. This may take some time. ===" ) from time import time from spglib import get_symmetry_dataset from pyxtal.symmetry import get_wyckoffs from pyxtal.crystal import random_crystal from pyxtal.crystal import cellsize from pymatgen.symmetry.analyzer import SpacegroupAnalyzer slow = [] failed = [] print(" Spacegroup # |Generated (SPG)|Generated (PMG)| Time Elapsed") skip = ( [] ) # [124, 139, 166, 167, 196, 202, 203, 204, 207, 209, 210, 216, 217, 219, 220, 221, 223, 225, 226, 227, 228, 229, 230] #slow to generate for sg in range(1, 231): if sg not in skip: multiplicity = len(get_wyckoffs(sg)[0]) / cellsize( sg) # multiplicity of the general position start = time() rand_crystal = random_crystal(sg, ["C"], [multiplicity], 1.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(sg) if rand_crystal.valid: check = False ans1 = get_symmetry_dataset(rand_crystal.spg_struct, symprec=1e-1) if ans1 is None: ans1 = "???" else: ans1 = ans1["number"] sga = SpacegroupAnalyzer(rand_crystal.struct) ans2 = "???" if sga is not None: try: ans2 = sga.get_space_group_number() except: ans2 = "???" if ans2 is None: ans2 = "???" # Compare expected and detected groups if ans1 == "???" and ans2 == "???": check = True elif ans1 == "???": if int(ans2) > sg: pass elif ans2 == "???": if int(ans1) > sg: pass else: if ans1 < sg and ans2 < sg: if compare_wyckoffs(sg, ans1) or compare_wyckoffs( sg, ans2): pass else: check = True # output cif files for incorrect space groups if check is True: if check_struct_group(rand_crystal, sg, dim=3): pass else: t += " xxxxx" outstructs.append(rand_crystal.struct) outstrings.append(str("3D_Atomic_" + str(sg) + ".vasp")) print("\t" + str(sg) + "\t|\t" + str(ans1) + "\t|\t" + str(ans2) + "\t|\t" + t) else: print("~~~~ Error: Could not generate space group " + str(sg) + " after " + t) failed.append(sg) if slow != []: print( "~~~~ The following space groups took more than 60 seconds to generate:" ) for i in slow: print(" " + str(i)) if failed != []: print("~~~~ The following space groups failed to generate:") for i in failed: print(" " + str(i))
def create_organism(self, id_generator, composition_space, constraints, random, dimension=3): """ Creates a random organism for the initial population. Returns a random organism, or None if an error was encountered during volume scaling. Note: for phase diagram searches, this is will not create structures with compositions equivalent to the endpoints of the composition space. Reference structures at those compositions should be provided with the FileOrganismCreator. Args: id_generator: the IDGenerator used to assign id numbers to all organisms composition_space: the CompositionSpace of the search constraints: the Constraints of the search random: a copy of Python's built in PRNG """ # make a random lattice #random_lattice = self.make_random_lattice(constraints, random) # get a list of species for the random organism random.seed(int(time.time() * 1e5)) species = self.get_species_list(composition_space, constraints, random) if species is None: # could happen for pd searches... return None # for each specie, generate a set of random fractional coordinates species_symbol = [ii.symbol for ii in species] symbol_set = list(set(species_symbol)) species_count = [species_symbol.count(el) for el in symbol_set] #species_dict={el:species_symbol.count(el) for el in symbol_set} #comp=Composition(species_dict) while True: if dimension == 0: sg = random.choice(range(1, 57)) elif dimension == 1: pass elif dimension == 2: pass else: sg = random.choice(range(1, 231)) #symbol, sg = get_symbol_and_number(sg, dimension) try: ret = random_crystal(sg, symbol_set, species_count, factor=1.0) except: pass if ret.valid: break random_cell = Cell(ret.struct.lattice, ret.struct.species, ret.struct.frac_coords) #random_coordinates = [] #for _ in range(len(species)): # random_coordinates.append([random.random(), random.random(), # random.random()]) # make a random cell #random_cell = Cell(random_lattice, species, random_coordinates) # optionally scale the volume of the random structure if not self.scale_volume(random_cell): return None # sometimes pymatgen's scaling algorithm crashes # make the random organism random_org = Organism(random_cell, id_generator, self.name, composition_space) print('Random organism creator making organism {} '.format( random_org.id)) return random_org
t0 = time() for i in range(N): run = True while run: sg = randint(2, 230) species = [] numIons = [] for ele in elements.keys(): species.append(ele) if len(elements[ele]) == 2: numIons.append(randint(elements[ele][0], elements[ele][1])) else: numIons.append(elements[ele]) crystal = random_crystal(sg, species, numIons, factor) if crystal.valid: struc = crystal.struct run = False print("SG requested: {0:3d} Vol: {1:6.2f} Time: {2:6.1f} mins".format( sg, struc.volume, (time() - t0) / 60.0)) dir1 = str(i) + "-" + str(struc.formula).replace(" ", "") [strucs, energies, times] = optimize(struc, dir1, modes=modes) os.chdir(dir0) if len(strucs) == len(modes): dump_json(strucs, energies, times, json1, json2) shutil.rmtree(dir1)
raise ValueError("Volume factor {:.2f} must be greater than 0.".format(factor)) #verbosity = options.verbosity attempts = options.attempts 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(" ", "")