def __init__(self,stru_source): try: stru = m.get_structure_by_material_id(stru_source) self.mpid = stru_source except: stru = Structure.from_file(stru_source) self.mpid = '' spa = SpacegroupAnalyzer(stru) self.stru = spa.get_primitive_standard_structure() self.stru_prim = spa.get_primitive_standard_structure() self.stru_conv = spa.get_conventional_standard_structure() formula = self.stru.composition.reduced_formula self.name = self.mpid+'_'+formula if self.mpid else formula try: self.bs = m.get_bandstructure_by_material_id(self.mpid) self.is_spin_polarized = self.bs.is_spin_polarized bs_exist = True self.pbevbm = self.bs.get_vbm() self.pbecbm = self.bs.get_cbm() self.kpbevbm = self.pbevbm['kpoint'].frac_coords self.kpbecbm = self.pbecbm['kpoint'].frac_coords except: bs_exist = False self.kpbevbm = None self.kpbecbm = None self.bs = None if not bs_exist: self.is_spin_polarized = False for elem in stru.composition.elements: if elem.is_transition_metal: self.is_spin_polarized = True break
def test_standardization(self): import numpy as np from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pymatgen.core.structure import Structure from pymatgen.core.lattice import Lattice from pymatgen.core.sites import PeriodicSite from supercellor.supercell import standardize_cell import itertools np.random.seed(10) for i in range(20): lattice = Lattice(1 * np.eye(3) + 0.5 * (np.random.random((3, 3)) - 0.5)) sites = [] for pos in itertools.product([-0.5, 0.5], repeat=3): sites.append( PeriodicSite("H", pos, lattice, coords_are_cartesian=True)) structure = Structure.from_sites(sites) sga = SpacegroupAnalyzer(structure) standardized_pymatgen = sga.get_primitive_standard_structure() standardized_supercellor = standardize_cell(structure, False) sga2 = SpacegroupAnalyzer(standardized_supercellor) standardized_pymatgen2 = sga.get_primitive_standard_structure() # Checking if I get to the same lattice when standardizing the structure standardize # by the supercellor. Note: standardized_pymatgen != standardized_supercellor # because they do not use the same algorithm self.assertTrue( ((standardized_pymatgen._lattice.matrix - standardized_pymatgen2._lattice.matrix)**2).sum() < 1e-6) self.assertTrue(standardized_pymatgen2 == standardized_pymatgen)
def primitive_structure(structure_file, fmt="json"): """ Args: structure_file: fmt: Returns: """ cathode = Cathode.from_file(structure_file) spg = SpacegroupAnalyzer(cathode) prim_structure_file = structure_file.split(".")[0] + "_conv" + "." + fmt spg.get_primitive_standard_structure().to(fmt, prim_structure_file)
def run_task(self, fw_spec): unitcell = Structure.from_file("POSCAR") supercell = self.get("supercell", None) if supercell is not None: os.system('cp POSCAR POSCAR-unitcell') unitcell.make_supercell(supercell) lepsilon = self.get("lepsilon", False) standardize = self.get("standardize", False) other_params = self.get("other_params", {}) user_incar_settings = self.get("user_incar_settings", {}) finder = SpacegroupAnalyzer(unitcell) prims = finder.get_primitive_standard_structure() # for lepsilon runs, the kpoints should be denser if lepsilon: kpoint_set = Generate_kpoints(prims, 0.02) struct = prims elif standardize: kpoint_set = Generate_kpoints(prims, 0.03) struct = prims else: kpoint_set = Generate_kpoints(unitcell, 0.03) struct = unitcell vis = MPStaticSet(struct, user_incar_settings=user_incar_settings, user_kpoints_settings=kpoint_set, sym_prec=self.get("sym_prec", 0.1), lepsilon=lepsilon, **other_params) vis.write_input(".")
def parallel_ND(root_dir, save_dir, fnames, max_Miller, sym_thresh): process_name = multiprocessing.current_process().name # initialize ND simulator nd_simulator = ND.NDSimulator(max_Miller=max_Miller) for filename in tqdm(fnames): cifpath = os.path.join(root_dir, "MP_cifs", filename+".cif") assert os.path.isfile(cifpath) cif_struct = Structure.from_file(cifpath) sga = SpacegroupAnalyzer(cif_struct, symprec=sym_thresh) # primitive cell primitive_struct = sga.get_primitive_standard_structure() # skip if this compound contains Ac or Pu (no neutron scattering length available) if (Element('Ac') in primitive_struct.species) or (Element('Pu') in primitive_struct.species): print('containing Ac or Pu, skipped {}'.format(filename), flush=True) continue # compute ND patterns primitive_features = nd_simulator.get_pattern(structure=primitive_struct) # save primitive diffraction pattern np.save(os.path.join(save_dir, filename+"_ND_primitive.npy"), primitive_features) # conventional cell conventional_struct = sga.get_conventional_standard_structure() conventional_features = nd_simulator.get_pattern(structure=conventional_struct) # save primitive diffraction pattern np.save(os.path.join(save_dir, filename+"_ND_conventional.npy"), conventional_features) print('Process {} is done..'.format(process_name), flush=True)
def parallel_computing(root_dir, fnames, wavelength, sym_thresh): # initialize XRD simulator xrd_simulator = xrd.XRDSimulator(wavelength=wavelength) for idx, filename in enumerate(fnames): if (idx + 1) % 100 == 0: print('this worker finished processing {} materials..'.format(idx + 1), flush=True) with open(os.path.join(root_dir, filename + ".cif")) as f: cif_struct = Structure.from_str(f.read(), fmt="cif") sga = SpacegroupAnalyzer(cif_struct, symprec=sym_thresh) # conventional cell conventional_struct = sga.get_conventional_standard_structure() _, conventional_recip_latt, conventional_features = \ xrd_simulator.get_pattern(structure=conventional_struct) # save conventional reciprocal lattice vector np.save(os.path.join(root_dir, filename+"_conventional_basis.npy"), \ conventional_recip_latt) # save conventional diffraction pattern np.save(os.path.join(root_dir, filename+"_conventional.npy"), \ np.array(conventional_features)) # primitive cell primitive_struct = sga.get_primitive_standard_structure() _, primitive_recip_latt, primitive_features = \ xrd_simulator.get_pattern(structure=primitive_struct) # save primitive reciprocal lattice vector np.save(os.path.join(root_dir, filename+"_primitive_basis.npy"), \ primitive_recip_latt) # save primitive diffraction pattern np.save(os.path.join(root_dir, filename+"_primitive.npy"), \ np.array(primitive_features))
def prim_cif(self, dst): """ primitive cellでのcifフォーマットをgetする """ finder = SpacegroupAnalyzer(self.structure) structure = finder.get_primitive_standard_structure() structure = finder.get_conventional_standard_structure() cif = CifWriter(structure, symprec=0.1) cif.write_file(dst)
def test_kpath_acentered(self): species = ["K", "La", "Ti"] coords = [[0.345, 5, 0.77298], [0.1345, 5.1, 0.77298], [0.7, 0.8, 0.9]] lattice = Lattice.orthorhombic(2, 9, 1) struct = Structure.from_spacegroup(38, lattice, species, coords) sga = SpacegroupAnalyzer(struct) struct_prim = sga.get_primitive_standard_structure(international_monoclinic=False) kpath = KPathLatimerMunro(struct_prim) kpoints = kpath._kpath["kpoints"] labels = list(kpoints.keys()) self.assertEqual( sorted(labels), sorted(["a", "b", "c", "d", "d_{1}", "e", "f", "q", "q_{1}", "Γ"]), ) self.assertAlmostEqual(kpoints["a"][0], 0.0) self.assertAlmostEqual(kpoints["a"][1], 0.4999999999999997) self.assertAlmostEqual(kpoints["a"][2], 0.0) self.assertAlmostEqual(kpoints["f"][0], -0.49999999999999933) self.assertAlmostEqual(kpoints["f"][1], 0.4999999999999992) self.assertAlmostEqual(kpoints["f"][2], 0.4999999999999999) self.assertAlmostEqual(kpoints["c"][0], 0.0) self.assertAlmostEqual(kpoints["c"][1], 0.0) self.assertAlmostEqual(kpoints["c"][2], 0.5) self.assertAlmostEqual(kpoints["b"][0], -0.5000000000000002) self.assertAlmostEqual(kpoints["b"][1], 0.500000000000000) self.assertAlmostEqual(kpoints["b"][2], 0.0) self.assertAlmostEqual(kpoints["Γ"][0], 0) self.assertAlmostEqual(kpoints["Γ"][1], 0) self.assertAlmostEqual(kpoints["Γ"][2], 0) self.assertAlmostEqual(kpoints["e"][0], 0.0) self.assertAlmostEqual(kpoints["e"][1], 0.49999999999999956) self.assertAlmostEqual(kpoints["e"][2], 0.5000000000000002) d = False if np.allclose(kpoints["d_{1}"], [0.2530864197530836, 0.25308641975308915, 0.0], atol=1e-5) or np.allclose( kpoints["d"], [0.2530864197530836, 0.25308641975308915, 0.0], atol=1e-5 ): d = True self.assertTrue(d) q = False if np.allclose(kpoints["q_{1}"], [0.2530864197530836, 0.25308641975308915, 0.5], atol=1e-5) or np.allclose( kpoints["q"], [0.2530864197530836, 0.25308641975308915, 0.5], atol=1e-5 ): q = True self.assertTrue(q)
def prim(src): """ primitive cell に変換 """ srcpos = Poscar.from_file(src) finder = SpacegroupAnalyzer(srcpos.structure) prim_str = finder.get_primitive_standard_structure() dstpos = Poscar(prim_str) dst = 'POSCAR_prim' Cabinet.reserve_file(dst) dstpos.write_file(dst)
def primitive(src="POSCAR"): """ primitiveに変換 """ srcpos = Poscar.from_file(src) finder = SpacegroupAnalyzer(srcpos.structure) prim = finder.get_primitive_standard_structure() dstpos = Poscar(prim) dst = "POSCAR_prim" Cabinet.reserve_file(dst) dstpos.write_file(dst)
def get_prim_structure(structure, symprec=0.01) -> Structure: """ Get the primitive structure. Args: structure: The structure. symprec: The symmetry precision in Angstrom. Returns: The primitive cell as a pymatgen Structure object. """ analyzer = SpacegroupAnalyzer(structure, symprec=symprec) return analyzer.get_primitive_standard_structure()
def get_highsympath(filename): ''' Get the high symmetry path of phonon spectrum. ''' struct = pmg.Structure.from_file(filename) finder = SpacegroupAnalyzer(struct) prims = finder.get_primitive_standard_structure() HKpath = HighSymmKpath(struct) Keys = list() Coords = list() for key in HKpath.kpath['kpoints']: Keys.append(key) Coords.append(HKpath.kpath['kpoints'][key]) count = 0 Keylist = list() Coordslist = list() for i in np.arange(len(Keys) - 1): if (count - 1) % 3 == 0: #count-1 can be intergely divided by 3 Keylist.append(Keys[0]) Coordslist.append(Coords[0]) count += 1 Keylist.append(Keys[i + 1]) Coordslist.append(Coords[i + 1]) count += 1 if (count - 1) % 3 == 0: Keylist.append(Keys[0]) Coordslist.append(Coords[0]) print('Please set \"BAND\" parameter of phonopy as this:%s' % os.linesep) for coord in Coordslist: print('%.4f %.4f %.4f ' % (coord[0], coord[1], coord[2]), end='') print('%s' % os.linesep) transmat = np.eye(3) if prims.num_sites != struct.num_sites: S_T = np.transpose(struct.lattice.matrix) P_T = np.transpose(prims.lattice.matrix) transmat = inv(S_T) @ P_T print( 'We notice your structure could have a primitive cell. Please set \"PRIMITIVE_AXIS\" parameter of phonopy as this:%s' % os.linesep) for coord in transmat: print('%.8f %.8f %.8f ' % (coord[0], coord[1], coord[2]), end='') print('%s' % os.linesep) return Keylist, Coordslist, prims, transmat
def symmetrize_cell(struc, mode='C'): """ symmetrize structure from pymatgen, and return the struc in conventional/primitive setting Args: struc: ase type mode: output conventional or primitive cell """ P_struc = ase2pymatgen(struc) finder = SpacegroupAnalyzer(P_struc,symprec=0.06,angle_tolerance=5) if mode == 'C': P_struc = finder.get_conventional_standard_structure() else: P_struc = finder.get_primitive_standard_structure() return pymatgen2ase(P_struc)
def get_smallest_expansion(structure : Structure, length : float): """ Finds the smallest expansion of the provided cell such that all sides are at minimum length. Will change shape of cell if it creates a better match :param structure: Unit cell to convert :param length: Minimum vector difference :return: """ from pymatgen.symmetry.analyzer import SpacegroupAnalyzer sga = SpacegroupAnalyzer(structure) structures = [] structures.append(structure) try: structures.append(structure.get_primitive_structure()) except: pass try: structures.append(structure.get_reduced_structure('niggli')) except: pass try: structures.append(structure.get_reduced_structure('LLL')) except: pass try: structures.append(sga.get_conventional_standard_structure()) except: pass try: structures.append(sga.get_primitive_standard_structure()) except: pass best_structure = None for s in structures: # type: Structure l = s.lattice expansion = [ ceil(length / vec) for vec in l.abc ] possible_structure = s * expansion if best_structure == None or len(possible_structure) < len(best_structure): best_structure = possible_structure if structure.site_properties and not best_structure.site_properties: def get_property(prop, atom): i = structure.species.index(atom) return structure.site_properties[prop][i] site_properties = { prop : [ get_property(prop, atom) for atom in best_structure.species ] for prop in structure.site_properties} best_structure = Structure(best_structure.lattice, best_structure.species, best_structure.frac_coords, site_properties=site_properties) return best_structure
def test_apply_transformation(self): structure = self.get_structure('TlBiSe2') min_atoms = 100 max_atoms = 1000 # Test the transformation without constraining trans_mat to be diagonal supercell_generator = CubicSupercellTransformation( min_atoms=min_atoms, max_atoms=max_atoms, min_length=13. ) superstructure = supercell_generator.apply_transformation(structure) num_atoms = superstructure.num_sites self.assertTrue(num_atoms >= min_atoms) self.assertTrue(num_atoms <= max_atoms) self.assertArrayAlmostEqual( superstructure.lattice.matrix[0], [1.49656087e+01, -1.11448000e-03, 9.04924836e+00] ) self.assertArrayAlmostEqual( superstructure.lattice.matrix[1], [-0.95005506, 14.95766342, 10.01819773] ) self.assertArrayAlmostEqual( superstructure.lattice.matrix[2], [3.69130000e-02, 4.09320200e-02, 5.90830153e+01] ) self.assertEqual(superstructure.num_sites, 448) self.assertArrayEqual( supercell_generator.transformation_matrix, np.array([[4, 0, 0], [1, 4, -4], [0, 0, 1]]) ) # Test the diagonal transformation structure2 = self.get_structure('Si') sga = SpacegroupAnalyzer(structure2) structure2 = sga.get_primitive_standard_structure() diagonal_supercell_generator = CubicSupercellTransformation( min_atoms=min_atoms, max_atoms=max_atoms, min_length=13., force_diagonal=True ) _ = diagonal_supercell_generator.apply_transformation(structure2) self.assertArrayEqual( diagonal_supercell_generator.transformation_matrix, np.eye(3) * 4 )
def test_apply_transformation(self): structure = self.get_structure('TlBiSe2') min_atoms = 100 max_atoms = 1000 num_nn_dists = 5 # Test the transformation without constraining trans_mat to be diagonal supercell_generator = CubicSupercellTransformation( min_atoms=min_atoms, max_atoms=max_atoms, num_nn_dists=num_nn_dists) superstructure = supercell_generator.apply_transformation(structure) num_atoms = superstructure.num_sites self.assertTrue(num_atoms >= min_atoms) self.assertTrue(num_atoms <= max_atoms) self.assertTrue(supercell_generator.smallest_dim >= num_nn_dists * supercell_generator.nn_dist) self.assertArrayAlmostEqual( superstructure.lattice.matrix[0], [1.49656087e+01, -1.11448000e-03, 9.04924836e+00]) self.assertArrayAlmostEqual(superstructure.lattice.matrix[1], [-0.95005506, 14.95766342, 10.01819773]) self.assertArrayAlmostEqual( superstructure.lattice.matrix[2], [3.69130000e-02, 4.09320200e-02, 5.90830153e+01]) self.assertEqual(superstructure.num_sites, 448) self.assertArrayEqual(supercell_generator.trans_mat, np.array([[4, 0, 0], [1, 4, -4], [0, 0, 1]])) # Test the diagonal transformation structure2 = self.get_structure('Si') sga = SpacegroupAnalyzer(structure2) structure2 = sga.get_primitive_standard_structure() structure2.to("poscar", filename="POSCAR-orig_si") diagonal_supercell_generator = CubicSupercellTransformation( min_atoms=min_atoms, max_atoms=max_atoms, num_nn_dists=num_nn_dists, force_diagonal_transformation=True) superstructure2 = diagonal_supercell_generator.apply_transformation( structure2) superstructure2.to("poscar", filename="POSCAR-diag_si") self.assertArrayEqual(diagonal_supercell_generator.trans_mat, np.array([[4, 0, 0], [0, 4, 0], [0, 0, 4]]))
def abi_sanitize(self, symprec=1e-3, angle_tolerance=5, primitive=True, primitive_standard=False): """ Returns a new structure in which: * Structure is refined. * Reduced to primitive settings. * Lattice vectors are exchanged if the triple product is negative Args: symprec: Symmetry precision used to refine the structure. if `symprec` is None, so structure refinement is peformed. primitive (bool): Whether to convert to a primitive cell. """ from pymatgen.transformations.standard_transformations import PrimitiveCellTransformation, SupercellTransformation structure = self.__class__.from_sites(self) # Refine structure if symprec is not None and angle_tolerance is not None: sym_finder = SpacegroupAnalyzer(structure=structure, symprec=symprec, angle_tolerance=angle_tolerance) structure = sym_finder.get_refined_structure() # Convert to primitive structure. if primitive: if primitive_standard: sym_finder_prim = SpacegroupAnalyzer(structure=structure, symprec=symprec, angle_tolerance=angle_tolerance) structure = sym_finder_prim.get_primitive_standard_structure() else: get_prim = PrimitiveCellTransformation() structure = get_prim.apply_transformation(structure) # Exchange last two lattice vectors if triple product is negative. m = structure.lattice.matrix x_prod = np.dot(np.cross(m[0], m[1]), m[2]) if x_prod < 0: trans = SupercellTransformation(((1, 0, 0), (0, 0, 1), (0, 1, 0))) structure = trans.apply_transformation(structure) m = structure.lattice.matrix x_prod = np.dot(np.cross(m[0], m[1]), m[2]) if x_prod < 0: raise RuntimeError("x_prod is still negative!") return structure
def add_cifs(doc): symprec = 0.1 struc = Structure.from_dict(doc["structure"]) sym_finder = SpacegroupAnalyzer(struc, symprec=symprec) doc["cif"] = str(CifWriter(struc)) doc["cifs"] = {} try: primitive = sym_finder.get_primitive_standard_structure() conventional = sym_finder.get_conventional_standard_structure() refined = sym_finder.get_refined_structure() doc["cifs"]["primitive"] = str(CifWriter(primitive)) doc["cifs"]["refined"] = str(CifWriter(refined, symprec=symprec)) doc["cifs"]["conventional_standard"] = str( CifWriter(conventional, symprec=symprec)) doc["cifs"]["computed"] = str(CifWriter(struc, symprec=symprec)) except: doc["cifs"]["primitive"] = None doc["cifs"]["refined"] = None doc["cifs"]["conventional_standard"] = None
def parallel_XRD(root_dir, save_dir, fnames, max_Miller, sym_thresh): process_name = multiprocessing.current_process().name # initialize XRD simulator xrd_simulator = XRD.XRDSimulator(max_Miller=max_Miller) for filename in tqdm(fnames): cifpath = os.path.join(root_dir, "MP_cifs", filename+".cif") assert os.path.isfile(cifpath) cif_struct = Structure.from_file(cifpath) sga = SpacegroupAnalyzer(cif_struct, symprec=sym_thresh) # primitive cell primitive_struct = sga.get_primitive_standard_structure() primitive_features = xrd_simulator.get_pattern(structure=primitive_struct) # save primitive diffraction pattern np.save(os.path.join(save_dir, filename+"_XRD_primitive.npy"), primitive_features) # conventional cell conventional_struct = sga.get_conventional_standard_structure() conventional_features = xrd_simulator.get_pattern(structure=conventional_struct) # save primitive diffraction pattern np.save(os.path.join(save_dir, filename+"_XRD_conventional.npy"), conventional_features) print('Process {} is done..'.format(process_name), flush=True)
def __init__(self, struct_bulk, min_dis=13.0, extrapolation=False): """ Args: struct_bulk_source: the bulk structure, pymatgen Structure object struct_defect: unconverged defect structure, the pymatgen Structure object, the one without relaxation is better. defect_type: the name of the defect on which the potential alignment isn't converged charge: the defect charge dfc_dist_add: the added distance between defects based on the origin one """ self.extrapolation = extrapolation self.struct_backup = struct_bulk finder = SpacegroupAnalyzer(struct_bulk,symprec=0.5) self.st_prim=finder.get_primitive_standard_structure() self.st_conv=finder.get_conventional_standard_structure() self.min_dis = min_dis self.find_optimized_supercell() best_supercell = self.optimized_supercell finder = SpacegroupAnalyzer(self.struct_orig,symprec=0.5) self.struct = finder.get_symmetrized_structure() self.inter_sites = get_interstitial_sites(self.struct_orig)
def __init__(self, structure, element): """ Initializes an Interstitial generator using structure motifs Args: structure (Structure): pymatgen structure object element (str or Element or Specie): element for the interstitial """ self.structure = structure self.element = element interstitial_finder = StructureMotifInterstitial(self.structure, self.element) self.defect_sites = list(interstitial_finder.enumerate_defectsites()) # for multiplicity, neccessary to get prim_structure spa = SpacegroupAnalyzer(self.structure, symprec=1e-2) prim_struct = spa.get_primitive_standard_structure() conv_prim_rat = int(self.structure.num_sites / prim_struct.num_sites) self.multiplicities = [ int(interstitial_finder.get_defectsite_multiplicity(def_ind) / conv_prim_rat) for def_ind in range(len(self.defect_sites)) ] self.count_def = 0 # for counting the index of the generated defect
def getFccEquilibrium(): # alat = 1.0 alat = math.sqrt(2.0) fcc = Structure( Lattice.cubic(alat), ["Co", "Co", "Co", "Co"], [[0.0, 0.0, 0.0], [0.0, 0.5, 0.5], [0.5, 0.0, 0.5], [0.5, 0.5, 0.0]]) # fcc = Structure( Lattice.cubic(alat), ["Co"], # [[0.0, 0.0, 0.0]] # ) # Find the primitive unit cell: from pymatgen.symmetry.analyzer import SpacegroupAnalyzer sym_finder = SpacegroupAnalyzer(fcc) fcc = sym_finder.get_primitive_standard_structure() # new_structure.to(fmt='poscar', filename='POSCAR_test_2') # Make a supercell n = 3 #3 fcc.make_supercell([n, n, n]) return fcc
def add_cifs(doc): struc = Structure.from_dict(doc["structure"]) sym_finder = SpacegroupAnalyzer(struc, symprec=0.1) doc["cif"] = str(CifWriter(struc)) doc["cifs"] = {} if sym_finder.get_hall(): primitive = sym_finder.get_primitive_standard_structure() conventional = sym_finder.get_conventional_standard_structure() refined = sym_finder.get_refined_structure() doc["cifs"]["primitive"] = str(CifWriter(primitive)) doc["cifs"]["refined"] = str(CifWriter(refined)) doc["cifs"]["conventional_standard"] = str(CifWriter(conventional)) doc["cifs"]["computed"] = str(CifWriter(struc)) doc["spacegroup"]["symbol"] = sym_finder.get_space_group_symbol() doc["spacegroup"]["number"] = sym_finder.get_space_group_number() doc["spacegroup"]["point_group"] = sym_finder.get_point_group_symbol() doc["spacegroup"]["crystal_system"] = sym_finder.get_crystal_system() doc["spacegroup"]["hall"] = sym_finder.get_hall() else: doc["cifs"]["primitive"] = None doc["cifs"]["refined"] = None doc["cifs"]["conventional_standard"] = None
def save_structures(entries, ids, cif=False, conv=False, ref=False, db=None): """ Args: ids (list): indexes of the entries to save """ fmt = 'cif' if cif else 'poscar' if db: db = ase.db.connect(db) for i in ids: e = entries[i - 1] sym = SpacegroupAnalyzer(e.structure) if conv: struct = sym.get_conventional_standard_structure() else: struct = sym.get_primitive_standard_structure() if db is not None: db.write(AseAtomsAdaptor.get_atoms(struct)) else: formula = e.data['pretty_formula'] filename = 'POSCAR_{}_{}'.format(formula, i) struct.to(filename=filename, fmt=fmt)
def __init__(self, crystal, calc_dihedral=False, symmetrize=True, bin_width=2.0): """Return a ADF object with the proper info""" self.width = bin_width self.calc_dihedral = calc_dihedral if symmetrize: finder = SpacegroupAnalyzer(crystal, symprec=0.02, angle_tolerance=5) #crystal = finder.get_conventional_standard_structure() crystal = finder.get_primitive_standard_structure() if calc_dihedral is True and len(crystal.sites) == 1: crystal.make_supercell([1, 1, 2]) self.get_neighbor_table(crystal) self.compute_angles(crystal.cart_coords) if len(self.angles) == 0: ADF = np.zeros(int(180 / self.width)) else: ADF, bins = np.histogram(self.angles, bins=int(180 / self.width), range=(0.5, 180.5)) ADF = np.array(ADF / ADF.sum()) self.ADF = ADF if self.calc_dihedral: if len(self.torsion_angles) == 0: DDF = np.zeros(int(180 / self.width)) else: DDF, bins = np.histogram(self.torsion_angles, bins=int(180 / self.width), range=(-89.5, 90.5)) DDF = np.array(DDF / DDF.sum()) self.DDF = DDF self.merge()
def __init__(self, structure, element): """ Initializes an Interstitial generator using structure motifs Args: structure (Structure): pymatgen structure object element (str or Element or Specie): element for the interstitial """ self.structure = structure self.element = element interstitial_finder = StructureMotifInterstitial( self.structure, self.element) self.defect_sites = list(interstitial_finder.enumerate_defectsites()) # for multiplicity, neccessary to get prim_structure spa = SpacegroupAnalyzer(self.structure, symprec=1e-2) prim_struct = spa.get_primitive_standard_structure() conv_prim_rat = int(self.structure.num_sites / prim_struct.num_sites) self.multiplicities = [ int( interstitial_finder.get_defectsite_multiplicity(def_ind) / conv_prim_rat) for def_ind in range(len(self.defect_sites)) ] self.count_def = 0 # for counting the index of the generated defect
def test_featurize(): """Test the featurization wrapper function.""" structure = Structure.from_file( os.path.join(THIS_DIR, "..", "..", "examples", "structures", "BaO2_mp-1105_computed.cif")) x, indices, names = featurize(structure) # pylint: disable=invalid-name assert len(x) == len(indices) == len(names) == 2 assert indices[0] == 0 assert indices[1] == 1 structure = Structure.from_file( os.path.join(THIS_DIR, "..", "..", "examples", "structures", "Mg_MOF_74.cif")) x, indices, names = featurize(structure) # pylint: disable=invalid-name assert len(x) == len(indices) == len(names) == 6 assert indices[0] == 0 assert indices[1] == 1 structure = Structure.from_file( os.path.join(THIS_DIR, "..", "structure_data_files", "RSM0027.cif")) x, indices, names = featurize(structure) # pylint: disable=invalid-name assert len(x) == len(indices) == len(names) == 2 spga = SpacegroupAnalyzer(structure) spga = SpacegroupAnalyzer(structure) x, indices, names = featurize( # pylint: disable=invalid-name spga.get_primitive_standard_structure()) assert len(x) == len(indices) == len(names) == 2 x, indices, names = featurize( # pylint: disable=invalid-name spga.get_conventional_standard_structure()) assert len(x) == len(indices) == len(names) == 4 structure = Structure.from_file( os.path.join(THIS_DIR, "..", "structure_data_files", "RSM0099.cif")) x, indices, names = featurize(structure) # pylint: disable=invalid-name assert len(x) == len(indices) == len(names) == 3 spga = SpacegroupAnalyzer(structure) x, indices, names = featurize( # pylint: disable=invalid-name spga.get_primitive_standard_structure()) # pylint: disable=invalid-name assert len(x) == len(indices) == len(names) == 3 x, indices, names = featurize( # pylint: disable=invalid-name spga.get_conventional_standard_structure()) assert len(x) == len(indices) == len(names) == 9 # Test Daniele's xyz file m = Molecule.from_file( # pylint: disable=invalid-name os.path.join(THIS_DIR, "..", "structure_data_files", "TSS03_structuredata.xyz")) lattice = np.array([ [6.4214088758454, 0.0, -2.0278718029537], [-1.7281031033172, 9.4571070308166, -5.4721686991526], [0.0, 0.0, 11.18087355], ]) s = Structure(lattice, [s.specie for s in m], m.cart_coords) # pylint: disable=invalid-name x, indices, names = featurize(s) # pylint: disable=invalid-name assert len(x) == len(indices) == len(names) == 2 assert indices[0] == 0 assert indices[1] == 1
NOTE! This script is based on Pymatgen(different from seekpath) --- syx ''' import os import pymatgen import numpy as np from pymatgen.core.structure import Structure from pymatgen.symmetry.analyzer import SpacegroupAnalyzer stru = Structure.from_file("POSCART2") spg = SpacegroupAnalyzer(stru, symprec=0.01, angle_tolerance=5) #fp = spg.find_primitive() fp = spg.get_primitive_standard_structure() stan = spg.get_conventional_standard_structure() with open("POSCAR-stand", 'w') as ST: ST.write("POSCAR-STAN\n" + "1.0\n") ST.write(str(stan.lattice) + '\n') # count {species: nums} spe = {} for i in stan.species: spe[i] = spe.get(i, 0) + 1 #print(spe) for i in spe.keys(): ST.write(str(i) + " ") ST.write('\n')
def write_etree(self, celltype, cartesian=False, bandstr=False, symprec=0.4, angle_tolerance=5): root = ET.Element('input') root.set( '{http://www.w3.org/2001/XMLSchema-instance}noNamespaceSchemaLocation', 'http://xml.exciting-code.org/excitinginput.xsd') title = ET.SubElement(root, 'title') title.text = self.title if cartesian: structure = ET.SubElement(root, 'structure', cartesian="true", speciespath="./") else: structure = ET.SubElement(root, 'structure', speciespath="./") crystal = ET.SubElement(structure, 'crystal') # set scale such that lattice vector can be given in Angstrom ang2bohr = const.value('Angstrom star') / const.value('Bohr radius') crystal.set('scale', str(ang2bohr)) # determine which structure to use finder = SpacegroupAnalyzer(self.structure, symprec=symprec, angle_tolerance=angle_tolerance) if celltype == 'primitive': new_struct = finder.get_primitive_standard_structure( international_monoclinic=False) elif celltype == 'conventional': new_struct = finder.get_conventional_standard_structure( international_monoclinic=False) elif celltype == 'unchanged': new_struct = self.structure else: raise ValueError('Type of unit cell not recognized!') # write lattice basis = new_struct.lattice.matrix for i in range(3): basevect = ET.SubElement(crystal, 'basevect') basevect.text = "%16.8f %16.8f %16.8f" % (basis[i][0], basis[i][1], basis[i][2]) # write atomic positions for each species index = 0 for i in new_struct.types_of_specie: species = ET.SubElement(structure, 'species', speciesfile=i.symbol + '.xml') sites = new_struct.indices_from_symbol(i.symbol) for j in sites: coord = "%16.8f %16.8f %16.8f" % (new_struct[j].frac_coords[0], new_struct[j].frac_coords[1], new_struct[j].frac_coords[2]) # obtain cartesian coords from fractional ones if needed if cartesian: coord2 = [] for k in range(3): inter = (new_struct[j].frac_coords[k] * basis[0][k] + new_struct[j].frac_coords[k] * basis[1][k] + new_struct[j].frac_coords[k] * basis[2][k]) * ang2bohr coord2.append(inter) coord = "%16.8f %16.8f %16.8f" % (coord2[0], coord2[1], coord2[2]) # write atomic positions index = index + 1 atom = ET.SubElement(species, 'atom', coord=coord) # write bandstructure if needed if bandstr and celltype == 'primitive': kpath = HighSymmKpath(new_struct, symprec=symprec, angle_tolerance=angle_tolerance) prop = ET.SubElement(root, 'properties') bandstrct = ET.SubElement(prop, 'bandstructure') for i in range(len(kpath.kpath['path'])): plot = ET.SubElement(bandstrct, 'plot1d') path = ET.SubElement(plot, 'path', steps='100') for j in range(len(kpath.kpath['path'][i])): symbol = kpath.kpath['path'][i][j] coords = kpath.kpath['kpoints'][symbol] coord = "%16.8f %16.8f %16.8f" % (coords[0], coords[1], coords[2]) if symbol == '\\Gamma': symbol = 'GAMMA' pt = ET.SubElement(path, 'point', coord=coord, label=symbol) elif bandstr and celltype is not 'primitive': raise ValueError("Bandstructure is only implemented for the \ standard primitive unit cell!") return root
class HighSymmKpath(object): """ This class looks for path along high symmetry lines in the Brillouin Zone. It is based on Setyawan, W., & Curtarolo, S. (2010). High-throughput electronic band structure calculations: Challenges and tools. Computational Materials Science, 49(2), 299-312. doi:10.1016/j.commatsci.2010.05.010 The symmetry is determined by spglib through the SpacegroupAnalyzer class Args: structure (Structure): Structure object symprec (float): Tolerance for symmetry finding angle_tolerance (float): Angle tolerance for symmetry finding. """ def __init__(self, structure, symprec=0.01, angle_tolerance=5): self._structure = structure self._sym = SpacegroupAnalyzer(structure, symprec=symprec, angle_tolerance=angle_tolerance) self._prim = self._sym.get_primitive_standard_structure(international_monoclinic=False) self._conv = self._sym.get_conventional_standard_structure(international_monoclinic=False) self._prim_rec = self._prim.lattice.reciprocal_lattice self._kpath = None lattice_type = self._sym.get_lattice_type() spg_symbol = self._sym.get_space_group_symbol() if lattice_type == "cubic": if "P" in spg_symbol: self._kpath = self.cubic() elif "F" in spg_symbol: self._kpath = self.fcc() elif "I" in spg_symbol: self._kpath = self.bcc() else: warn("Unexpected value for spg_symbol: %s" % spg_symbol) elif lattice_type == "tetragonal": if "P" in spg_symbol: self._kpath = self.tet() elif "I" in spg_symbol: a = self._conv.lattice.abc[0] c = self._conv.lattice.abc[2] if c < a: self._kpath = self.bctet1(c, a) else: self._kpath = self.bctet2(c, a) else: warn("Unexpected value for spg_symbol: %s" % spg_symbol) elif lattice_type == "orthorhombic": a = self._conv.lattice.abc[0] b = self._conv.lattice.abc[1] c = self._conv.lattice.abc[2] if "P" in spg_symbol: self._kpath = self.orc() elif "F" in spg_symbol: if 1 / a ** 2 > 1 / b ** 2 + 1 / c ** 2: self._kpath = self.orcf1(a, b, c) elif 1 / a ** 2 < 1 / b ** 2 + 1 / c ** 2: self._kpath = self.orcf2(a, b, c) else: self._kpath = self.orcf3(a, b, c) elif "I" in spg_symbol: self._kpath = self.orci(a, b, c) elif "C" in spg_symbol: self._kpath = self.orcc(a, b, c) else: warn("Unexpected value for spg_symbol: %s" % spg_symbol) elif lattice_type == "hexagonal": self._kpath = self.hex() elif lattice_type == "rhombohedral": alpha = self._prim.lattice.lengths_and_angles[1][0] if alpha < 90: self._kpath = self.rhl1(alpha * pi / 180) else: self._kpath = self.rhl2(alpha * pi / 180) elif lattice_type == "monoclinic": a, b, c = self._conv.lattice.abc alpha = self._conv.lattice.lengths_and_angles[1][0] # beta = self._conv.lattice.lengths_and_angles[1][1] if "P" in spg_symbol: self._kpath = self.mcl(b, c, alpha * pi / 180) elif "C" in spg_symbol: kgamma = self._prim_rec.lengths_and_angles[1][2] if kgamma > 90: self._kpath = self.mclc1(a, b, c, alpha * pi / 180) if kgamma == 90: self._kpath = self.mclc2(a, b, c, alpha * pi / 180) if kgamma < 90: if b * cos(alpha * pi / 180) / c + b ** 2 * sin(alpha) ** 2 / a ** 2 < 1: self._kpath = self.mclc3(a, b, c, alpha * pi / 180) if b * cos(alpha * pi / 180) / c + b ** 2 * sin(alpha) ** 2 / a ** 2 == 1: self._kpath = self.mclc4(a, b, c, alpha * pi / 180) if b * cos(alpha * pi / 180) / c + b ** 2 * sin(alpha) ** 2 / a ** 2 > 1: self._kpath = self.mclc5(a, b, c, alpha * pi / 180) else: warn("Unexpected value for spg_symbol: %s" % spg_symbol) elif lattice_type == "triclinic": kalpha = self._prim_rec.lengths_and_angles[1][0] kbeta = self._prim_rec.lengths_and_angles[1][1] kgamma = self._prim_rec.lengths_and_angles[1][2] if kalpha > 90 and kbeta > 90 and kgamma > 90: self._kpath = self.tria() if kalpha < 90 and kbeta < 90 and kgamma < 90: self._kpath = self.trib() if kalpha > 90 and kbeta > 90 and kgamma == 90: self._kpath = self.tria() if kalpha < 90 and kbeta < 90 and kgamma == 90: self._kpath = self.trib() else: warn("Unknown lattice type %s" % lattice_type) @property def structure(self): """ Returns: The standardized primitive structure """ return self._prim @property def conventional(self): """ Returns: The conventional cell structure """ return self._conv @property def prim(self): """ Returns: The primitive cell structure """ return self._prim @property def prim_rec(self): """ Returns: The primitive reciprocal cell structure """ return self._prim_rec @property def kpath(self): """ Returns: The symmetry line path in reciprocal space """ return self._kpath def get_kpoints(self, line_density=20, coords_are_cartesian=True): """ Returns: the kpoints along the paths in cartesian coordinates together with the labels for symmetry points -Wei """ list_k_points = [] sym_point_labels = [] for b in self.kpath["path"]: for i in range(1, len(b)): start = np.array(self.kpath["kpoints"][b[i - 1]]) end = np.array(self.kpath["kpoints"][b[i]]) distance = np.linalg.norm( self._prim_rec.get_cartesian_coords(start) - self._prim_rec.get_cartesian_coords(end) ) nb = int(ceil(distance * line_density)) sym_point_labels.extend([b[i - 1]] + [""] * (nb - 1) + [b[i]]) list_k_points.extend( [ self._prim_rec.get_cartesian_coords(start) + float(i) / float(nb) * (self._prim_rec.get_cartesian_coords(end) - self._prim_rec.get_cartesian_coords(start)) for i in range(0, nb + 1) ] ) if coords_are_cartesian: return list_k_points, sym_point_labels else: frac_k_points = [self._prim_rec.get_fractional_coords(k) for k in list_k_points] return frac_k_points, sym_point_labels def cubic(self): self.name = "CUB" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "X": np.array([0.0, 0.5, 0.0]), "R": np.array([0.5, 0.5, 0.5]), "M": np.array([0.5, 0.5, 0.0]), } path = [["\Gamma", "X", "M", "\Gamma", "R", "X"], ["M", "R"]] return {"kpoints": kpoints, "path": path} def fcc(self): self.name = "FCC" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "K": np.array([3.0 / 8.0, 3.0 / 8.0, 3.0 / 4.0]), "L": np.array([0.5, 0.5, 0.5]), "U": np.array([5.0 / 8.0, 1.0 / 4.0, 5.0 / 8.0]), "W": np.array([0.5, 1.0 / 4.0, 3.0 / 4.0]), "X": np.array([0.5, 0.0, 0.5]), } path = [["\Gamma", "X", "W", "K", "\Gamma", "L", "U", "W", "L", "K"], ["U", "X"]] return {"kpoints": kpoints, "path": path} def bcc(self): self.name = "BCC" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "H": np.array([0.5, -0.5, 0.5]), "P": np.array([0.25, 0.25, 0.25]), "N": np.array([0.0, 0.0, 0.5]), } path = [["\Gamma", "H", "N", "\Gamma", "P", "H"], ["P", "N"]] return {"kpoints": kpoints, "path": path} def tet(self): self.name = "TET" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "A": np.array([0.5, 0.5, 0.5]), "M": np.array([0.5, 0.5, 0.0]), "R": np.array([0.0, 0.5, 0.5]), "X": np.array([0.0, 0.5, 0.0]), "Z": np.array([0.0, 0.0, 0.5]), } path = [["\Gamma", "X", "M", "\Gamma", "Z", "R", "A", "Z"], ["X", "R"], ["M", "A"]] return {"kpoints": kpoints, "path": path} def bctet1(self, c, a): self.name = "BCT1" eta = (1 + c ** 2 / a ** 2) / 4.0 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "M": np.array([-0.5, 0.5, 0.5]), "N": np.array([0.0, 0.5, 0.0]), "P": np.array([0.25, 0.25, 0.25]), "X": np.array([0.0, 0.0, 0.5]), "Z": np.array([eta, eta, -eta]), "Z_1": np.array([-eta, 1 - eta, eta]), } path = [["\Gamma", "X", "M", "\Gamma", "Z", "P", "N", "Z_1", "M"], ["X", "P"]] return {"kpoints": kpoints, "path": path} def bctet2(self, c, a): self.name = "BCT2" eta = (1 + a ** 2 / c ** 2) / 4.0 zeta = a ** 2 / (2 * c ** 2) kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "N": np.array([0.0, 0.5, 0.0]), "P": np.array([0.25, 0.25, 0.25]), "\Sigma": np.array([-eta, eta, eta]), "\Sigma_1": np.array([eta, 1 - eta, -eta]), "X": np.array([0.0, 0.0, 0.5]), "Y": np.array([-zeta, zeta, 0.5]), "Y_1": np.array([0.5, 0.5, -zeta]), "Z": np.array([0.5, 0.5, -0.5]), } path = [["\Gamma", "X", "Y", "\Sigma", "\Gamma", "Z", "\Sigma_1", "N", "P", "Y_1", "Z"], ["X", "P"]] return {"kpoints": kpoints, "path": path} def orc(self): self.name = "ORC" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "R": np.array([0.5, 0.5, 0.5]), "S": np.array([0.5, 0.5, 0.0]), "T": np.array([0.0, 0.5, 0.5]), "U": np.array([0.5, 0.0, 0.5]), "X": np.array([0.5, 0.0, 0.0]), "Y": np.array([0.0, 0.5, 0.0]), "Z": np.array([0.0, 0.0, 0.5]), } path = [["\Gamma", "X", "S", "Y", "\Gamma", "Z", "U", "R", "T", "Z"], ["Y", "T"], ["U", "X"], ["S", "R"]] return {"kpoints": kpoints, "path": path} def orcf1(self, a, b, c): self.name = "ORCF1" zeta = (1 + a ** 2 / b ** 2 - a ** 2 / c ** 2) / 4 eta = (1 + a ** 2 / b ** 2 + a ** 2 / c ** 2) / 4 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "A": np.array([0.5, 0.5 + zeta, zeta]), "A_1": np.array([0.5, 0.5 - zeta, 1 - zeta]), "L": np.array([0.5, 0.5, 0.5]), "T": np.array([1, 0.5, 0.5]), "X": np.array([0.0, eta, eta]), "X_1": np.array([1, 1 - eta, 1 - eta]), "Y": np.array([0.5, 0.0, 0.5]), "Z": np.array([0.5, 0.5, 0.0]), } path = [["\Gamma", "Y", "T", "Z", "\Gamma", "X", "A_1", "Y"], ["T", "X_1"], ["X", "A", "Z"], ["L", "\Gamma"]] return {"kpoints": kpoints, "path": path} def orcf2(self, a, b, c): self.name = "ORCF2" phi = (1 + c ** 2 / b ** 2 - c ** 2 / a ** 2) / 4 eta = (1 + a ** 2 / b ** 2 - a ** 2 / c ** 2) / 4 delta = (1 + b ** 2 / a ** 2 - b ** 2 / c ** 2) / 4 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "C": np.array([0.5, 0.5 - eta, 1 - eta]), "C_1": np.array([0.5, 0.5 + eta, eta]), "D": np.array([0.5 - delta, 0.5, 1 - delta]), "D_1": np.array([0.5 + delta, 0.5, delta]), "L": np.array([0.5, 0.5, 0.5]), "H": np.array([1 - phi, 0.5 - phi, 0.5]), "H_1": np.array([phi, 0.5 + phi, 0.5]), "X": np.array([0.0, 0.5, 0.5]), "Y": np.array([0.5, 0.0, 0.5]), "Z": np.array([0.5, 0.5, 0.0]), } path = [ ["\Gamma", "Y", "C", "D", "X", "\Gamma", "Z", "D_1", "H", "C"], ["C_1", "Z"], ["X", "H_1"], ["H", "Y"], ["L", "\Gamma"], ] return {"kpoints": kpoints, "path": path} def orcf3(self, a, b, c): self.name = "ORCF3" zeta = (1 + a ** 2 / b ** 2 - a ** 2 / c ** 2) / 4 eta = (1 + a ** 2 / b ** 2 + a ** 2 / c ** 2) / 4 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "A": np.array([0.5, 0.5 + zeta, zeta]), "A_1": np.array([0.5, 0.5 - zeta, 1 - zeta]), "L": np.array([0.5, 0.5, 0.5]), "T": np.array([1, 0.5, 0.5]), "X": np.array([0.0, eta, eta]), "X_1": np.array([1, 1 - eta, 1 - eta]), "Y": np.array([0.5, 0.0, 0.5]), "Z": np.array([0.5, 0.5, 0.0]), } path = [["\Gamma", "Y", "T", "Z", "\Gamma", "X", "A_1", "Y"], ["X", "A", "Z"], ["L", "\Gamma"]] return {"kpoints": kpoints, "path": path} def orci(self, a, b, c): self.name = "ORCI" zeta = (1 + a ** 2 / c ** 2) / 4 eta = (1 + b ** 2 / c ** 2) / 4 delta = (b ** 2 - a ** 2) / (4 * c ** 2) mu = (a ** 2 + b ** 2) / (4 * c ** 2) kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "L": np.array([-mu, mu, 0.5 - delta]), "L_1": np.array([mu, -mu, 0.5 + delta]), "L_2": np.array([0.5 - delta, 0.5 + delta, -mu]), "R": np.array([0.0, 0.5, 0.0]), "S": np.array([0.5, 0.0, 0.0]), "T": np.array([0.0, 0.0, 0.5]), "W": np.array([0.25, 0.25, 0.25]), "X": np.array([-zeta, zeta, zeta]), "X_1": np.array([zeta, 1 - zeta, -zeta]), "Y": np.array([eta, -eta, eta]), "Y_1": np.array([1 - eta, eta, -eta]), "Z": np.array([0.5, 0.5, -0.5]), } path = [["\Gamma", "X", "L", "T", "W", "R", "X_1", "Z", "\Gamma", "Y", "S", "W"], ["L_1", "Y"], ["Y_1", "Z"]] return {"kpoints": kpoints, "path": path} def orcc(self, a, b, c): self.name = "ORCC" zeta = (1 + a ** 2 / b ** 2) / 4 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "A": np.array([zeta, zeta, 0.5]), "A_1": np.array([-zeta, 1 - zeta, 0.5]), "R": np.array([0.0, 0.5, 0.5]), "S": np.array([0.0, 0.5, 0.0]), "T": np.array([-0.5, 0.5, 0.5]), "X": np.array([zeta, zeta, 0.0]), "X_1": np.array([-zeta, 1 - zeta, 0.0]), "Y": np.array([-0.5, 0.5, 0]), "Z": np.array([0.0, 0.0, 0.5]), } path = [["\Gamma", "X", "S", "R", "A", "Z", "\Gamma", "Y", "X_1", "A_1", "T", "Y"], ["Z", "T"]] return {"kpoints": kpoints, "path": path} def hex(self): self.name = "HEX" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "A": np.array([0.0, 0.0, 0.5]), "H": np.array([1.0 / 3.0, 1.0 / 3.0, 0.5]), "K": np.array([1.0 / 3.0, 1.0 / 3.0, 0.0]), "L": np.array([0.5, 0.0, 0.5]), "M": np.array([0.5, 0.0, 0.0]), } path = [["\Gamma", "M", "K", "\Gamma", "A", "L", "H", "A"], ["L", "M"], ["K", "H"]] return {"kpoints": kpoints, "path": path} def rhl1(self, alpha): self.name = "RHL1" eta = (1 + 4 * cos(alpha)) / (2 + 4 * cos(alpha)) nu = 3.0 / 4.0 - eta / 2.0 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "B": np.array([eta, 0.5, 1.0 - eta]), "B_1": np.array([1.0 / 2.0, 1.0 - eta, eta - 1.0]), "F": np.array([0.5, 0.5, 0.0]), "L": np.array([0.5, 0.0, 0.0]), "L_1": np.array([0.0, 0.0, -0.5]), "P": np.array([eta, nu, nu]), "P_1": np.array([1.0 - nu, 1.0 - nu, 1.0 - eta]), "P_2": np.array([nu, nu, eta - 1.0]), "Q": np.array([1.0 - nu, nu, 0.0]), "X": np.array([nu, 0.0, -nu]), "Z": np.array([0.5, 0.5, 0.5]), } path = [["\Gamma", "L", "B_1"], ["B", "Z", "\Gamma", "X"], ["Q", "F", "P_1", "Z"], ["L", "P"]] return {"kpoints": kpoints, "path": path} def rhl2(self, alpha): self.name = "RHL2" eta = 1 / (2 * tan(alpha / 2.0) ** 2) nu = 3.0 / 4.0 - eta / 2.0 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "F": np.array([0.5, -0.5, 0.0]), "L": np.array([0.5, 0.0, 0.0]), "P": np.array([1 - nu, -nu, 1 - nu]), "P_1": np.array([nu, nu - 1.0, nu - 1.0]), "Q": np.array([eta, eta, eta]), "Q_1": np.array([1.0 - eta, -eta, -eta]), "Z": np.array([0.5, -0.5, 0.5]), } path = [["\Gamma", "P", "Z", "Q", "\Gamma", "F", "P_1", "Q_1", "L", "Z"]] return {"kpoints": kpoints, "path": path} def mcl(self, b, c, beta): self.name = "MCL" eta = (1 - b * cos(beta) / c) / (2 * sin(beta) ** 2) nu = 0.5 - eta * c * cos(beta) / b kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "A": np.array([0.5, 0.5, 0.0]), "C": np.array([0.0, 0.5, 0.5]), "D": np.array([0.5, 0.0, 0.5]), "D_1": np.array([0.5, 0.5, -0.5]), "E": np.array([0.5, 0.5, 0.5]), "H": np.array([0.0, eta, 1.0 - nu]), "H_1": np.array([0.0, 1.0 - eta, nu]), "H_2": np.array([0.0, eta, -nu]), "M": np.array([0.5, eta, 1.0 - nu]), "M_1": np.array([0.5, 1 - eta, nu]), "M_2": np.array([0.5, 1 - eta, nu]), "X": np.array([0.0, 0.5, 0.0]), "Y": np.array([0.0, 0.0, 0.5]), "Y_1": np.array([0.0, 0.0, -0.5]), "Z": np.array([0.5, 0.0, 0.0]), } path = [["\Gamma", "Y", "H", "C", "E", "M_1", "A", "X", "H_1"], ["M", "D", "Z"], ["Y", "D"]] return {"kpoints": kpoints, "path": path} def mclc1(self, a, b, c, alpha): self.name = "MCLC1" zeta = (2 - b * cos(alpha) / c) / (4 * sin(alpha) ** 2) eta = 0.5 + 2 * zeta * c * cos(alpha) / b psi = 0.75 - a ** 2 / (4 * b ** 2 * sin(alpha) ** 2) phi = psi + (0.75 - psi) * b * cos(alpha) / c kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "N": np.array([0.5, 0.0, 0.0]), "N_1": np.array([0.0, -0.5, 0.0]), "F": np.array([1 - zeta, 1 - zeta, 1 - eta]), "F_1": np.array([zeta, zeta, eta]), "F_2": np.array([-zeta, -zeta, 1 - eta]), #'F_3': np.array([1 - zeta, -zeta, 1 - eta]), "I": np.array([phi, 1 - phi, 0.5]), "I_1": np.array([1 - phi, phi - 1, 0.5]), "L": np.array([0.5, 0.5, 0.5]), "M": np.array([0.5, 0.0, 0.5]), "X": np.array([1 - psi, psi - 1, 0.0]), "X_1": np.array([psi, 1 - psi, 0.0]), "X_2": np.array([psi - 1, -psi, 0.0]), "Y": np.array([0.5, 0.5, 0.0]), "Y_1": np.array([-0.5, -0.5, 0.0]), "Z": np.array([0.0, 0.0, 0.5]), } path = [ ["\Gamma", "Y", "F", "L", "I"], ["I_1", "Z", "F_1"], ["Y", "X_1"], ["X", "\Gamma", "N"], ["M", "\Gamma"], ] return {"kpoints": kpoints, "path": path} def mclc2(self, a, b, c, alpha): self.name = "MCLC2" zeta = (2 - b * cos(alpha) / c) / (4 * sin(alpha) ** 2) eta = 0.5 + 2 * zeta * c * cos(alpha) / b psi = 0.75 - a ** 2 / (4 * b ** 2 * sin(alpha) ** 2) phi = psi + (0.75 - psi) * b * cos(alpha) / c kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "N": np.array([0.5, 0.0, 0.0]), "N_1": np.array([0.0, -0.5, 0.0]), "F": np.array([1 - zeta, 1 - zeta, 1 - eta]), "F_1": np.array([zeta, zeta, eta]), "F_2": np.array([-zeta, -zeta, 1 - eta]), "F_3": np.array([1 - zeta, -zeta, 1 - eta]), "I": np.array([phi, 1 - phi, 0.5]), "I_1": np.array([1 - phi, phi - 1, 0.5]), "L": np.array([0.5, 0.5, 0.5]), "M": np.array([0.5, 0.0, 0.5]), "X": np.array([1 - psi, psi - 1, 0.0]), "X_1": np.array([psi, 1 - psi, 0.0]), "X_2": np.array([psi - 1, -psi, 0.0]), "Y": np.array([0.5, 0.5, 0.0]), "Y_1": np.array([-0.5, -0.5, 0.0]), "Z": np.array([0.0, 0.0, 0.5]), } path = [["\Gamma", "Y", "F", "L", "I"], ["I_1", "Z", "F_1"], ["N", "\Gamma", "M"]] return {"kpoints": kpoints, "path": path} def mclc3(self, a, b, c, alpha): self.name = "MCLC3" mu = (1 + b ** 2 / a ** 2) / 4.0 delta = b * c * cos(alpha) / (2 * a ** 2) zeta = mu - 0.25 + (1 - b * cos(alpha) / c) / (4 * sin(alpha) ** 2) eta = 0.5 + 2 * zeta * c * cos(alpha) / b phi = 1 + zeta - 2 * mu psi = eta - 2 * delta kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "F": np.array([1 - phi, 1 - phi, 1 - psi]), "F_1": np.array([phi, phi - 1, psi]), "F_2": np.array([1 - phi, -phi, 1 - psi]), "H": np.array([zeta, zeta, eta]), "H_1": np.array([1 - zeta, -zeta, 1 - eta]), "H_2": np.array([-zeta, -zeta, 1 - eta]), "I": np.array([0.5, -0.5, 0.5]), "M": np.array([0.5, 0.0, 0.5]), "N": np.array([0.5, 0.0, 0.0]), "N_1": np.array([0.0, -0.5, 0.0]), "X": np.array([0.5, -0.5, 0.0]), "Y": np.array([mu, mu, delta]), "Y_1": np.array([1 - mu, -mu, -delta]), "Y_2": np.array([-mu, -mu, -delta]), "Y_3": np.array([mu, mu - 1, delta]), "Z": np.array([0.0, 0.0, 0.5]), } path = [["\Gamma", "Y", "F", "H", "Z", "I", "F_1"], ["H_1", "Y_1", "X", "\Gamma", "N"], ["M", "\Gamma"]] return {"kpoints": kpoints, "path": path} def mclc4(self, a, b, c, alpha): self.name = "MCLC4" mu = (1 + b ** 2 / a ** 2) / 4.0 delta = b * c * cos(alpha) / (2 * a ** 2) zeta = mu - 0.25 + (1 - b * cos(alpha) / c) / (4 * sin(alpha) ** 2) eta = 0.5 + 2 * zeta * c * cos(alpha) / b phi = 1 + zeta - 2 * mu psi = eta - 2 * delta kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "F": np.array([1 - phi, 1 - phi, 1 - psi]), "F_1": np.array([phi, phi - 1, psi]), "F_2": np.array([1 - phi, -phi, 1 - psi]), "H": np.array([zeta, zeta, eta]), "H_1": np.array([1 - zeta, -zeta, 1 - eta]), "H_2": np.array([-zeta, -zeta, 1 - eta]), "I": np.array([0.5, -0.5, 0.5]), "M": np.array([0.5, 0.0, 0.5]), "N": np.array([0.5, 0.0, 0.0]), "N_1": np.array([0.0, -0.5, 0.0]), "X": np.array([0.5, -0.5, 0.0]), "Y": np.array([mu, mu, delta]), "Y_1": np.array([1 - mu, -mu, -delta]), "Y_2": np.array([-mu, -mu, -delta]), "Y_3": np.array([mu, mu - 1, delta]), "Z": np.array([0.0, 0.0, 0.5]), } path = [["\Gamma", "Y", "F", "H", "Z", "I"], ["H_1", "Y_1", "X", "\Gamma", "N"], ["M", "\Gamma"]] return {"kpoints": kpoints, "path": path} def mclc5(self, a, b, c, alpha): self.name = "MCLC5" zeta = (b ** 2 / a ** 2 + (1 - b * cos(alpha) / c) / sin(alpha) ** 2) / 4 eta = 0.5 + 2 * zeta * c * cos(alpha) / b mu = eta / 2 + b ** 2 / (4 * a ** 2) - b * c * cos(alpha) / (2 * a ** 2) nu = 2 * mu - zeta rho = 1 - zeta * a ** 2 / b ** 2 omega = (4 * nu - 1 - b ** 2 * sin(alpha) ** 2 / a ** 2) * c / (2 * b * cos(alpha)) delta = zeta * c * cos(alpha) / b + omega / 2 - 0.25 kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "F": np.array([nu, nu, omega]), "F_1": np.array([1 - nu, 1 - nu, 1 - omega]), "F_2": np.array([nu, nu - 1, omega]), "H": np.array([zeta, zeta, eta]), "H_1": np.array([1 - zeta, -zeta, 1 - eta]), "H_2": np.array([-zeta, -zeta, 1 - eta]), "I": np.array([rho, 1 - rho, 0.5]), "I_1": np.array([1 - rho, rho - 1, 0.5]), "L": np.array([0.5, 0.5, 0.5]), "M": np.array([0.5, 0.0, 0.5]), "N": np.array([0.5, 0.0, 0.0]), "N_1": np.array([0.0, -0.5, 0.0]), "X": np.array([0.5, -0.5, 0.0]), "Y": np.array([mu, mu, delta]), "Y_1": np.array([1 - mu, -mu, -delta]), "Y_2": np.array([-mu, -mu, -delta]), "Y_3": np.array([mu, mu - 1, delta]), "Z": np.array([0.0, 0.0, 0.5]), } path = [ ["\Gamma", "Y", "F", "L", "I"], ["I_1", "Z", "H", "F_1"], ["H_1", "Y_1", "X", "\Gamma", "N"], ["M", "\Gamma"], ] return {"kpoints": kpoints, "path": path} def tria(self): self.name = "TRI1a" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "L": np.array([0.5, 0.5, 0.0]), "M": np.array([0.0, 0.5, 0.5]), "N": np.array([0.5, 0.0, 0.5]), "R": np.array([0.5, 0.5, 0.5]), "X": np.array([0.5, 0.0, 0.0]), "Y": np.array([0.0, 0.5, 0.0]), "Z": np.array([0.0, 0.0, 0.5]), } path = [["X", "\Gamma", "Y"], ["L", "\Gamma", "Z"], ["N", "\Gamma", "M"], ["R", "\Gamma"]] return {"kpoints": kpoints, "path": path} def trib(self): self.name = "TRI1b" kpoints = { "\Gamma": np.array([0.0, 0.0, 0.0]), "L": np.array([0.5, -0.5, 0.0]), "M": np.array([0.0, 0.0, 0.5]), "N": np.array([-0.5, -0.5, 0.5]), "R": np.array([0.0, -0.5, 0.5]), "X": np.array([0.0, -0.5, 0.0]), "Y": np.array([0.5, 0.0, 0.0]), "Z": np.array([-0.5, 0.0, 0.5]), } path = [["X", "\Gamma", "Y"], ["L", "\Gamma", "Z"], ["N", "\Gamma", "M"], ["R", "\Gamma"]] return {"kpoints": kpoints, "path": path}
from pymatgen import Structure, Lattice, Specie from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pmg_lammps import RelaxSet, LammpsRun, LammpsData, LammpsPotentials supercell = (5, 5, 5) a = 4.1990858 # From evaluation of potential lattice = Lattice.from_parameters(a, a, a, 90, 90, 90) mg = Specie('Mg', 1.4) o = Specie('O', -1.4) atoms = [mg, o] sites = [[0, 0, 0], [0.5, 0.5, 0.5]] structure = Structure.from_spacegroup(225, lattice, atoms, sites) spga = SpacegroupAnalyzer(structure) structure = spga.get_primitive_standard_structure() print(structure) directory = 'runs/lattice' lammps_potentials = LammpsPotentials( pair={ (mg, mg): '1309362.2766468062 0.104 0.0', (mg, o): '9892.357 0.20199 0.0', (o, o): '2145.7345 0.3 30.2222' }) lammps_data = LammpsData.from_structure(structure * supercell, potentials=lammps_potentials, include_charge=True)
parser = argparse.ArgumentParser(description=str1) parser.add_argument( 'POSCAR', action='store', type=str, help="POSCAR is the name of the input file in VASP5 format.") parser.add_argument('tol', type=float, help="""the tolerance for analysing space group. A float number less than 0.05 is recommended.""") args = parser.parse_args() #------------------------------------------------------------ tol = args.tol structure = Structure.from_file("POSCAR") spg_analy = SpacegroupAnalyzer(structure) primitive_standard_structure = spg_analy.get_primitive_standard_structure( international_monoclinic=False) primitive_standard_structure.to(fmt="poscar", filename="PPOSCAR") structure = Structure.from_file("PPOSCAR") finder = SpacegroupAnalyzer(structure, symprec=tol, angle_tolerance=5) spg_s = finder.get_space_group_symbol() spg_n = finder.get_space_group_number() #pg = finder.get_point_group_symbol() print("Spacegroup (symbol) : ", spg_s) print("Spacegroup (number) : ", spg_n) #print ("pointgroup : ", pg) pather = HighSymmKpath(structure, symprec=tol, angle_tolerance=5) kpoints_path = pather.kpath kk = kpoints_path["kpoints"] pp = kpoints_path["path"]
def test_magnetic_kpath_generation(self): struct_file_path = os.path.join(test_dir_structs, "LaMnO3_magnetic.mcif") struct = Structure.from_file(struct_file_path) mga = CollinearMagneticStructureAnalyzer(struct) col_spin_orig = mga.get_structure_with_spin() col_spin_orig.add_spin_by_site([0.0] * 20) col_spin_sym = SpacegroupAnalyzer(col_spin_orig) col_spin_prim = col_spin_sym.get_primitive_standard_structure( international_monoclinic=False) magmom_vec_list = [np.zeros(3) for site in col_spin_prim] magmom_vec_list[4:8] = [ np.array([3.87, 3.87, 0.0]), np.array([3.87, 3.87, 0.0]), np.array([-3.87, -3.87, 0.0]), np.array([-3.87, -3.87, 0.0]), ] col_spin_prim.add_site_property("magmom", magmom_vec_list) kpath = KPathLatimerMunro(col_spin_prim, has_magmoms=True) kpoints = kpath._kpath["kpoints"] labels = list(kpoints.keys()) self.assertEqual( sorted(labels), sorted(["a", "b", "c", "d", "d_{1}", "e", "f", "g", "g_{1}", "Γ"]), ) self.assertAlmostEqual(kpoints["e"][0], -0.4999999999999998) self.assertAlmostEqual(kpoints["e"][1], 0.0) self.assertAlmostEqual(kpoints["e"][2], 0.5000000000000002) self.assertAlmostEqual(kpoints["g"][0], -0.4999999999999999) self.assertAlmostEqual(kpoints["g"][1], -0.49999999999999994) self.assertAlmostEqual(kpoints["g"][2], 0.5000000000000002) self.assertAlmostEqual(kpoints["a"][0], -0.4999999999999999) self.assertAlmostEqual(kpoints["a"][1], 0.0) self.assertAlmostEqual(kpoints["a"][2], 0.0) self.assertAlmostEqual(kpoints["g_{1}"][0], 0.4999999999999999) self.assertAlmostEqual(kpoints["g_{1}"][1], -0.5) self.assertAlmostEqual(kpoints["g_{1}"][2], 0.5000000000000001) self.assertAlmostEqual(kpoints["f"][0], 0.0) self.assertAlmostEqual(kpoints["f"][1], -0.5) self.assertAlmostEqual(kpoints["f"][2], 0.5000000000000002) self.assertAlmostEqual(kpoints["c"][0], 0.0) self.assertAlmostEqual(kpoints["c"][1], 0.0) self.assertAlmostEqual(kpoints["c"][2], 0.5000000000000001) self.assertAlmostEqual(kpoints["b"][0], 0.0) self.assertAlmostEqual(kpoints["b"][1], -0.5) self.assertAlmostEqual(kpoints["b"][2], 0.0) self.assertAlmostEqual(kpoints["Γ"][0], 0) self.assertAlmostEqual(kpoints["Γ"][1], 0) self.assertAlmostEqual(kpoints["Γ"][2], 0) d = False if np.allclose(kpoints["d_{1}"], [-0.5, -0.5, 0.0], atol=1e-5) or np.allclose( kpoints["d"], [-0.5, -0.5, 0.0], atol=1e-5): d = True self.assertTrue(d) g = False if np.allclose(kpoints["g_{1}"], [-0.5, -0.5, 0.5], atol=1e-5) or np.allclose( kpoints["g"], [-0.5, -0.5, 0.5], atol=1e-5): g = True self.assertTrue(g)
def reformat_prim(structure): sym = SpacegroupAnalyzer(structure.structure) prim = sym.get_primitive_standard_structure() return (prim)
def write_etree(self, celltype, cartesian=False, bandstr=False, symprec=0.4, angle_tolerance=5, **kwargs): """ Writes the exciting input parameters to an xml object. Args: celltype (str): Choice of unit cell. Can be either the unit cell from self.structure ("unchanged"), the conventional cell ("conventional"), or the primitive unit cell ("primitive"). cartesian (bool): Whether the atomic positions are provided in Cartesian or unit-cell coordinates. Default is False. bandstr (bool): Whether the bandstructure path along the HighSymmKpath is included in the input file. Only supported if the celltype is set to "primitive". Default is False. symprec (float): Tolerance for the symmetry finding. Default is 0.4. angle_tolerance (float): Angle tolerance for the symmetry finding. Default is 5. **kwargs: Additional parameters for the input file. Returns: ET.Element containing the input XML structure """ root = ET.Element("input") root.set( "{http://www.w3.org/2001/XMLSchema-instance}noNamespaceSchemaLocation", "http://xml.exciting-code.org/excitinginput.xsd", ) title = ET.SubElement(root, "title") title.text = self.title if cartesian: structure = ET.SubElement(root, "structure", cartesian="true", speciespath="./") else: structure = ET.SubElement(root, "structure", speciespath="./") crystal = ET.SubElement(structure, "crystal") # set scale such that lattice vector can be given in Angstrom ang2bohr = const.value("Angstrom star") / const.value("Bohr radius") crystal.set("scale", str(ang2bohr)) # determine which structure to use finder = SpacegroupAnalyzer(self.structure, symprec=symprec, angle_tolerance=angle_tolerance) if celltype == "primitive": new_struct = finder.get_primitive_standard_structure( international_monoclinic=False) elif celltype == "conventional": new_struct = finder.get_conventional_standard_structure( international_monoclinic=False) elif celltype == "unchanged": new_struct = self.structure else: raise ValueError("Type of unit cell not recognized!") # write lattice basis = new_struct.lattice.matrix for i in range(3): basevect = ET.SubElement(crystal, "basevect") basevect.text = "{:16.8f} {:16.8f} {:16.8f}".format( basis[i][0], basis[i][1], basis[i][2], ) # write atomic positions for each species index = 0 for i in sorted(new_struct.types_of_species, key=lambda el: el.X): species = ET.SubElement(structure, "species", speciesfile=i.symbol + ".xml") sites = new_struct.indices_from_symbol(i.symbol) for j in sites: coord = "{:16.8f} {:16.8f} {:16.8f}".format( new_struct[j].frac_coords[0], new_struct[j].frac_coords[1], new_struct[j].frac_coords[2], ) # obtain Cartesian coords from fractional ones if needed if cartesian: coord2 = [] for k in range(3): inter = (new_struct[j].frac_coords[k] * basis[0][k] + new_struct[j].frac_coords[k] * basis[1][k] + new_struct[j].frac_coords[k] * basis[2][k]) * ang2bohr coord2.append(inter) coord = f"{coord2[0]:16.8f} {coord2[1]:16.8f} {coord2[2]:16.8f}" # write atomic positions index = index + 1 _ = ET.SubElement(species, "atom", coord=coord) # write bandstructure if needed if bandstr and celltype == "primitive": kpath = HighSymmKpath(new_struct, symprec=symprec, angle_tolerance=angle_tolerance) prop = ET.SubElement(root, "properties") bandstrct = ET.SubElement(prop, "bandstructure") for i in range(len(kpath.kpath["path"])): plot = ET.SubElement(bandstrct, "plot1d") path = ET.SubElement(plot, "path", steps="100") for j in range(len(kpath.kpath["path"][i])): symbol = kpath.kpath["path"][i][j] coords = kpath.kpath["kpoints"][symbol] coord = f"{coords[0]:16.8f} {coords[1]:16.8f} {coords[2]:16.8f}" if symbol == "\\Gamma": symbol = "GAMMA" _ = ET.SubElement(path, "point", coord=coord, label=symbol) elif bandstr and celltype != "primitive": raise ValueError("Bandstructure is only implemented for the \ standard primitive unit cell!") # write extra parameters from kwargs if provided self._dicttoxml(kwargs, root) return root
def test_get_primitive_standard_structure(self): parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001) self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001) self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001) self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145) parser = CifParser(os.path.join(test_dir, 'btet_1915.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 105.015053349) self.assertAlmostEqual(prim.lattice.beta, 105.015053349) self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999) self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791) parser = CifParser(os.path.join(test_dir, 'orci_1010.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001) self.assertAlmostEqual(prim.lattice.beta, 105.856239333) self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001) self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852) parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 164.985257335) self.assertAlmostEqual(prim.lattice.a, 15.854897098324196) self.assertAlmostEqual(prim.lattice.b, 15.854897098324196) self.assertAlmostEqual(prim.lattice.c, 3.99648651) parser = CifParser(os.path.join(test_dir, 'orac_632475.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 144.40557588533386) self.assertAlmostEqual(prim.lattice.a, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.b, 5.2005185662155391) self.assertAlmostEqual(prim.lattice.c, 3.5372412099999999) parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999) self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779) self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569) self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002) parser = CifParser(os.path.join(test_dir, 'hex_1170.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 120) self.assertAlmostEqual(prim.lattice.a, 3.699919902005897) self.assertAlmostEqual(prim.lattice.b, 3.699919902005897) self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003) parser = CifParser(os.path.join(test_dir, 'rhomb_3478_conv.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 28.049186140546812) self.assertAlmostEqual(prim.lattice.beta, 28.049186140546812) self.assertAlmostEqual(prim.lattice.gamma, 28.049186140546812) self.assertAlmostEqual(prim.lattice.a, 5.9352627428399982) self.assertAlmostEqual(prim.lattice.b, 5.9352627428399982) self.assertAlmostEqual(prim.lattice.c, 5.9352627428399982)
def test_get_primitive_standard_structure(self): parser = CifParser(os.path.join(test_dir, 'bcc_1927.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 109.47122063400001) self.assertAlmostEqual(prim.lattice.beta, 109.47122063400001) self.assertAlmostEqual(prim.lattice.gamma, 109.47122063400001) self.assertAlmostEqual(prim.lattice.a, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.b, 7.9657251015812145) self.assertAlmostEqual(prim.lattice.c, 7.9657251015812145) parser = CifParser(os.path.join(test_dir, 'btet_1915.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 105.015053349) self.assertAlmostEqual(prim.lattice.beta, 105.015053349) self.assertAlmostEqual(prim.lattice.gamma, 118.80658411899999) self.assertAlmostEqual(prim.lattice.a, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.b, 4.1579321075608791) self.assertAlmostEqual(prim.lattice.c, 4.1579321075608791) parser = CifParser(os.path.join(test_dir, 'orci_1010.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 134.78923546600001) self.assertAlmostEqual(prim.lattice.beta, 105.856239333) self.assertAlmostEqual(prim.lattice.gamma, 91.276341676000001) self.assertAlmostEqual(prim.lattice.a, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.b, 3.8428217771014852) self.assertAlmostEqual(prim.lattice.c, 3.8428217771014852) parser = CifParser(os.path.join(test_dir, 'orcc_1003.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 164.985257335) self.assertAlmostEqual(prim.lattice.a, 15.854897098324196) self.assertAlmostEqual(prim.lattice.b, 15.854897098324196) self.assertAlmostEqual(prim.lattice.c, 3.99648651) parser = CifParser(os.path.join(test_dir, 'monoc_1028.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 63.579155761999999) self.assertAlmostEqual(prim.lattice.beta, 116.42084423747779) self.assertAlmostEqual(prim.lattice.gamma, 148.47965136208569) self.assertAlmostEqual(prim.lattice.a, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.b, 7.2908007159612325) self.assertAlmostEqual(prim.lattice.c, 6.8743926325200002) parser = CifParser(os.path.join(test_dir, 'rhomb_1170.cif')) structure = parser.get_structures(False)[0] s = SpacegroupAnalyzer(structure, symprec=1e-2) prim = s.get_primitive_standard_structure() self.assertAlmostEqual(prim.lattice.alpha, 90) self.assertAlmostEqual(prim.lattice.beta, 90) self.assertAlmostEqual(prim.lattice.gamma, 120) self.assertAlmostEqual(prim.lattice.a, 3.699919902005897) self.assertAlmostEqual(prim.lattice.b, 3.699919902005897) self.assertAlmostEqual(prim.lattice.c, 6.9779585500000003)
(options, args) = parser.parse_args() cmd = ' mpirun -np 24 /share/apps/bin/vasp541-2013sp1/vasp_std > vasp_log' opt_dir = 'Opt' static_dir = 'Static' band_dir = 'Band' dos_dir = 'Dos' todo = Read_POSCARS(options.posfile) count = 0 for struc_id in todo: count = count + 1 finder = SpacegroupAnalyzer(struc_id, symprec=0.06, angle_tolerance=5) struc = finder.get_primitive_standard_structure() if max(struc.lattice.angles) > 140 or min(struc.lattice.angles) < 40: struc = finder.get_conventional_standard_structure() if count < 10: label = '00' + str(count) elif count < 100: label = '0' + str(count) else: label = str(count) Name = label + '-' + str(struc.formula).replace(" ", "") print('Creating new directory: ', Name) if os.path.isdir(Name) is False: os.mkdir(Name) os.chdir(Name) if os.path.exists('static-vasprun.xml') is False:
def write_etree(self, celltype, cartesian=False, bandstr=False, symprec=0.4, angle_tolerance=5): root=ET.Element('input') root.set('{http://www.w3.org/2001/XMLSchema-instance}noNamespaceSchemaLocation', 'http://xml.exciting-code.org/excitinginput.xsd') title=ET.SubElement(root,'title') title.text=self.title if cartesian: structure=ET.SubElement(root,'structure',cartesian="true",speciespath="./") else: structure=ET.SubElement(root,'structure',speciespath="./") crystal=ET.SubElement(structure,'crystal') # set scale such that lattice vector can be given in Angstrom ang2bohr=const.value('Angstrom star')/const.value('Bohr radius') crystal.set('scale',str(ang2bohr)) # determine which structure to use finder=SpacegroupAnalyzer(self.structure,symprec=symprec, angle_tolerance=angle_tolerance) if celltype=='primitive': new_struct=finder.get_primitive_standard_structure(international_monoclinic=False) elif celltype=='conventional': new_struct=finder.get_conventional_standard_structure(international_monoclinic=False) elif celltype=='unchanged': new_struct=self.structure else: raise ValueError('Type of unit cell not recognized!') # write lattice basis=new_struct.lattice.matrix for i in range(3): basevect=ET.SubElement(crystal,'basevect') basevect.text= "%16.8f %16.8f %16.8f" % (basis[i][0], basis[i][1], basis[i][2]) # write atomic positions for each species index=0 for i in new_struct.types_of_specie: species=ET.SubElement(structure,'species',speciesfile=i.symbol+ '.xml') sites=new_struct.indices_from_symbol(i.symbol) for j in sites: coord="%16.8f %16.8f %16.8f" % (new_struct[j].frac_coords[0], new_struct[j].frac_coords[1], new_struct[j].frac_coords[2]) # obtain cartesian coords from fractional ones if needed if cartesian: coord2=[] for k in range(3): inter=(new_struct[j].frac_coords[k]*basis[0][k]+\ new_struct[j].frac_coords[k]*basis[1][k]+\ new_struct[j].frac_coords[k]*basis[2][k])*ang2bohr coord2.append(inter) coord="%16.8f %16.8f %16.8f" % (coord2[0], coord2[1], coord2[2]) # write atomic positions index=index+1 atom=ET.SubElement(species,'atom',coord=coord) # write bandstructure if needed if bandstr and celltype=='primitive': kpath=HighSymmKpath(new_struct, symprec=symprec, angle_tolerance=angle_tolerance) prop=ET.SubElement(root,'properties') bandstrct=ET.SubElement(prop,'bandstructure') for i in range(len(kpath.kpath['path'])): plot=ET.SubElement(bandstrct,'plot1d') path=ET.SubElement(plot, 'path',steps='100') for j in range(len(kpath.kpath['path'][i])): symbol=kpath.kpath['path'][i][j] coords=kpath.kpath['kpoints'][symbol] coord="%16.8f %16.8f %16.8f" % (coords[0], coords[1], coords[2]) if symbol=='\\Gamma': symbol='GAMMA' pt=ET.SubElement(path,'point',coord=coord,label=symbol) elif bandstr and celltype is not 'primitive': raise ValueError("Bandstructure is only implemented for the \ standard primitive unit cell!") return root