def test_apply_transformation(self): enum_trans = EnumerateStructureTransformation(refine_structure=True) p = Poscar.from_file(os.path.join(test_dir, 'POSCAR.LiFePO4'), check_for_POTCAR=False) struct = p.structure expected_ans = [1, 3, 1] for i, frac in enumerate([0.25, 0.5, 0.75]): trans = SubstitutionTransformation({'Fe': {'Fe': frac}}) s = trans.apply_transformation(struct) oxitrans = OxidationStateDecorationTransformation( {'Li': 1, 'Fe': 2, 'P': 5, 'O': -2}) s = oxitrans.apply_transformation(s) alls = enum_trans.apply_transformation(s, 100) self.assertEqual(len(alls), expected_ans[i]) self.assertIsInstance(trans.apply_transformation(s), Structure) for s in alls: self.assertIn("energy", s) # make sure it works for non-oxidation state decorated structure trans = SubstitutionTransformation({'Fe': {'Fe': 0.5}}) s = trans.apply_transformation(struct) alls = enum_trans.apply_transformation(s, 100) self.assertEqual(len(alls), 3) self.assertIsInstance(trans.apply_transformation(s), Structure) for s in alls: self.assertNotIn("energy", s)
def test_apply_transformation(self): enum_trans = EnumerateStructureTransformation(refine_structure=True) p = Poscar.from_file(os.path.join(test_dir, 'POSCAR.LiFePO4'), check_for_POTCAR=False) struct = p.structure expected_ans = [1, 3, 1] for i, frac in enumerate([0.25, 0.5, 0.75]): trans = SubstitutionTransformation({'Fe': {'Fe': frac}}) s = trans.apply_transformation(struct) oxitrans = OxidationStateDecorationTransformation({'Li': 1, 'Fe': 2, 'P': 5, 'O': -2}) s = oxitrans.apply_transformation(s) alls = enum_trans.apply_transformation(s, 100) self.assertEquals(len(alls), expected_ans[i]) self.assertIsInstance(trans.apply_transformation(s), Structure) for s in alls: self.assertIn("energy", s) #make sure it works for non-oxidation state decorated structure trans = SubstitutionTransformation({'Fe': {'Fe': 0.5}}) s = trans.apply_transformation(struct) alls = enum_trans.apply_transformation(s, 100) self.assertEquals(len(alls), 3) self.assertIsInstance(trans.apply_transformation(s), Structure) for s in alls: self.assertNotIn("energy", s)
def test_max_disordered_sites(self): l = Lattice.cubic(4) s_orig = Structure(l, [{"Li": 0.2, "Na": 0.2, "K": 0.6}, {"O": 1}], [[0, 0, 0], [0.5, 0.5, 0.5]]) est = EnumerateStructureTransformation(max_cell_size=None, max_disordered_sites=5) s = est.apply_transformation(s_orig) self.assertEqual(len(s), 8)
def test_max_disordered_sites(self): l = Lattice.cubic(4) s_orig = Structure(l, [{"Li": 0.2, "Na": 0.2, "K": 0.6}, {"O": 1}], [[0, 0, 0], [0.5, 0.5, 0.5]]) est = EnumerateStructureTransformation(max_cell_size=None, max_disordered_sites=5) dd = est.apply_transformation(s_orig, return_ranked_list=100) self.assertEqual(len(dd), 9) for d in dd: self.assertEqual(len(d["structure"]), 10)
def enumerate_ordering(self, structure): # Generate the disordered structure first. s = Structure.from_sites(structure.sites) for indices, fraction in zip(self._indices, self._fractions): for ind in indices: new_sp = {sp: occu * fraction for sp, occu in structure[ind].species_and_occu.items()} s[ind] = new_sp # Perform enumeration from pymatgen.transformations.advanced_transformations import EnumerateStructureTransformation trans = EnumerateStructureTransformation() return trans.apply_transformation(s, 10000)
def _enumerate_ordering(self, structure): # Generate the disordered structure first. s = structure.copy() for indices, fraction in zip(self.indices, self.fractions): for ind in indices: new_sp = {sp: occu * fraction for sp, occu in structure[ind].species.items()} s[ind] = new_sp # Perform enumeration from pymatgen.transformations.advanced_transformations import ( EnumerateStructureTransformation, ) trans = EnumerateStructureTransformation() return trans.apply_transformation(s, 10000)
def enumerate_ordering(self, structure): # Generate the disordered structure first. s = Structure.from_sites(structure.sites) for indices, fraction in zip(self._indices, self._fractions): for ind in indices: new_sp = { sp: occu * fraction for sp, occu in structure[ind].species_and_occu.items() } s[ind] = new_sp # Perform enumeration from pymatgen.transformations.advanced_transformations import \ EnumerateStructureTransformation trans = EnumerateStructureTransformation() return trans.apply_transformation(s, 10000)
def enumerate_ordering(self, structure): # Generate the disordered structure first. editor = StructureEditor(structure) for indices, fraction in zip(self._indices, self._fractions): for ind in indices: new_sp = {sp: occu * fraction for sp, occu in structure[ind].species_and_occu.items()} editor.replace_site(ind, new_sp) mod_s = editor.modified_structure # Perform enumeration from pymatgen.transformations.advanced_transformations import \ EnumerateStructureTransformation trans = EnumerateStructureTransformation() return trans.apply_transformation(mod_s, 10000)
def test_to_from_dict(self): if not enumlib_present: raise SkipTest("enumlib not present. Skipping " "EnumerateStructureTransformationTest...") trans = EnumerateStructureTransformation() d = trans.to_dict trans = EnumerateStructureTransformation.from_dict(d) self.assertEqual(trans.symm_prec, 0.1)
def test_apply_transformation(self): enum_trans = EnumerateStructureTransformation(refine_structure=True) enum_trans2 = EnumerateStructureTransformation(refine_structure=True, sort_criteria="nsites") p = Poscar.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "POSCAR.LiFePO4"), check_for_POTCAR=False) struct = p.structure expected_ans = [1, 3, 1] for i, frac in enumerate([0.25, 0.5, 0.75]): trans = SubstitutionTransformation({"Fe": {"Fe": frac}}) s = trans.apply_transformation(struct) oxitrans = OxidationStateDecorationTransformation({"Li": 1, "Fe": 2, "P": 5, "O": -2}) s = oxitrans.apply_transformation(s) alls = enum_trans.apply_transformation(s, 100) self.assertEqual(len(alls), expected_ans[i]) self.assertIsInstance(trans.apply_transformation(s), Structure) for ss in alls: self.assertIn("energy", ss) alls = enum_trans2.apply_transformation(s, 100) self.assertEqual(len(alls), expected_ans[i]) self.assertIsInstance(trans.apply_transformation(s), Structure) for ss in alls: self.assertIn("num_sites", ss) # make sure it works for non-oxidation state decorated structure trans = SubstitutionTransformation({"Fe": {"Fe": 0.5}}) s = trans.apply_transformation(struct) alls = enum_trans.apply_transformation(s, 100) self.assertEqual(len(alls), 3) self.assertIsInstance(trans.apply_transformation(s), Structure) for s in alls: self.assertNotIn("energy", s)
def std_enumeration(subbed_struct, cell_dim, coll_limit): """Performs an enumeration using the EnumLib library. Args: subbed_struct (Structure): A structure with some amount of disorder. cell_dim (list): A list of maximum a, b, and c cell dimension limits. coll_limit (int): Limit to the number of structures produced. Returns: A list of structure dictionaries? I need to test this. """ est = EnumerateStructureTransformation(min_cell_size=1, max_cell_size=max(cell_dim)) if coll_limit == 1: return est.apply_transformation(subbed_struct, return_ranked_list=False) else: return est.apply_transformation(subbed_struct, return_ranked_list=coll_limit)
def test_apply_transformation_mult(self): # Test returning multiple structures from each transformation. disord = Structure(np.eye(3) * 4.209, [{"Cs+": 0.5, "K+": 0.5}, "Cl-"], [[0, 0, 0], [0.5, 0.5, 0.5]]) disord.make_supercell([2, 2, 1]) tl = [EnumerateStructureTransformation(), OrderDisorderedStructureTransformation()] t = SuperTransformation(tl, nstructures_per_trans=10) self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 8) t = SuperTransformation(tl) self.assertEqual(len(t.apply_transformation(disord, return_ranked_list=20)), 2)
def test_occu_tol(self): s = PymatgenTest.get_structure("Li2O") s["Li+"] = {"Li+": 0.48} trans = EnumerateStructureTransformation(occu_tol=4) ss = trans.apply_transformation(s, return_ranked_list=10) self.assertEqual(len(ss), 1) s = PymatgenTest.get_structure("Li2O") s["Li+"] = {"Li+": 0.24} trans = EnumerateStructureTransformation(max_cell_size=2, occu_tol=4) ss = trans.apply_transformation(s, return_ranked_list=10) self.assertEqual(len(ss), 3)
from pymatgen.io.vasp.sets import batch_write_input, MPRelaxSet from pymatgen.io.vasp.sets import batch_write_input, MPRelaxSet structure = Structure.from_file("1.cif") structure[0] = {"Fe2+": 1 / 3, "Li+": 2 / 3} structure[1] = {"Fe2+": 1 / 3, "Li+": 2 / 3} structure[2] = {"Fe2+": 1 / 3, "Li+": 2 / 3} structure[3] = {"S2-": 1} structure[4] = {"O2-": 1} structure structure.make_supercell([2, 2, 2]) structure enum = EnumerateStructureTransformation() enumerated = enum.apply_transformation( structure, return_ranked_list=100) # return no more than 100 structures structures = [d["structure"] for d in enumerated] print("%d structures returned." % len(structures)) from pymatgen.analysis.energy_models import EwaldElectrostaticModel ed = EwaldElectrostaticModel() #ed.get_energy(structures[1]) structures20 = structures[:20] batch_write_input(elect_stru, vasp_input_set=MPRelaxSet) # elect_stru=structures20=structures[::10] # for st in elect_stru:
def test_to_from_dict(self): trans = EnumerateStructureTransformation() d = trans.as_dict() trans = EnumerateStructureTransformation.from_dict(d) self.assertEqual(trans.symm_prec, 0.1)
def disorder_in_supercell( pristineStruct, # substSpecies={}, supercell_size=[1, 1, 1], number_of_struct=10): ini = pristineStruct.copy() # substitued structures ===================================== # substitued_1 = sd.SubstitutionTransformation( # {"Na": {"Li": 0.5, "Fe": 0.5}}).apply_transformation(ini) substitued_2 = sd.SubstitutionTransformation({ "Ti": { "Ti": 7 / 8, "Fe": 1 / 8 } }).apply_transformation(ini) ini = substitued_2 # GENERATE OXIDATION STATES ================================ try: oxi = sd.AutoOxiStateDecorationTransformation().apply_transformation( ini) except ValueError: print("Forced to set oxidation by hand") oxi.add_oxidation_state_by_element({ "Na": 1, "Mg": 2, "Mn": 3.5, "O": -2, "Li": 1, "Ca": 2, "Fe": 3, "Zn": 4, "Co": 2.5, "Ti": 4, "S": -2, 'P': 5 }) print(oxi) # transform into 2,2,2 supercell [x, y, z] = supercell_size megaOxi = sd.SupercellTransformation.from_scaling_factors( x, y, z).apply_transformation(oxi) # dictPri = {'structure': megaOxi, 'id': "pristine"} print(megaOxi) # chosenList.append(dictPri) #uncomment to compute pistine ! # # generation of a list of ordered structures from the disordered one chosenList = [] try: type_of_algo = input( "type of algo : [E]numlib (more efficient but weaker) // [P]ymatgen built-in (slower but safer)" )[0] except BaseException: type_of_algo = "E" print("trying E then P sequence") try: if type_of_algo == "E": enum = EnumerateStructureTransformation( min_cell_size=1, max_cell_size=None, symm_prec=0.1, refine_structure=False, enum_precision_parameter=0.1, check_ordered_symmetry=True, max_disordered_sites=100, sort_criteria='ewald', timeout=None) enumList = enum.apply_transformation( megaOxi, return_ranked_list=number_of_struct) except Exception as ex: print( "error during enumlib method : {} \n fall back to [P]ymatgen buit-in method", ex) type_of_algo = "P" try: if type_of_algo == "P": enumList = sd.OrderDisorderedStructureTransformation( ).apply_transformation(megaOxi, return_ranked_list=number_of_struct) except Exception as ex: print( "error during [P]ymatgen buit-in method {} \n You're on your own beyond this point...", ex) for i, chosenStruct in enumerate(enumList): chosenList.append({ 'structure': chosenStruct['structure'], "id": str(i + 1) }) print(chosenList) return chosenList
from pymatgen import Structure from pymatgen.symmetry.analyzer import SpacegroupAnalyzer from pymatgen.transformations.advanced_transformations import EnumerateStructureTransformation from pymatgen.io.vasp.sets import batch_write_input, MPRelaxSet structure = Structure.from_file( "D:/Program Files (x86)/python2/file/EntryWithCollCode418490.cif") # (获取文件 当在自己电脑中调试的时候需要将相关的路径统一一下) print(structure) # loop over all sites in the structure for i, site in enumerate(structure): # (enumerate 为枚举类型) # change the occupancy of Li+ disordered sites to 0.5 if not site.is_ordered: structure[i] = {"Li+": 0.5} print("The composition after adjustments is %s." % structure.composition.reduced_formula) analyzer = SpacegroupAnalyzer(structure) # SpacegroupAnalyzer为空间群分析 晶体内部结构中全部对称要素的集合称为 “空间群” 。 # 一切晶体结构中总共只能有230种不同的对称要素组合方式,即230个空间群所谓点空间群, # 是由一个平移群和一个点群对称操作组合而成的,它的一般对称操作可以写成(R | t (αβγ)),其中R表示点群对称操作,t(αβγ)表示平移操作 # 为了保持可排序的顺序,我们只在原始单元上执行枚举。原始单元可以使用*空间群分析器*获得 prim_cell = analyzer.find_primitive() print(prim_cell) enum = EnumerateStructureTransformation() # 变换枚举结构 enumerated = enum.apply_transformation(prim_cell, 90) # 在这需要限制返回结构的数量 structures = [d["structure"] for d in enumerated] print("%d structures returned." % len(structures))
from pymatgen import Structure from pymatgen.symmetry.analyzer import SpacegroupAnalyzer #空间群分析器 from pymatgen.transformations.advanced_transformations import EnumerateStructureTransformation #枚举结构转换 from pymatgen.io.vasp.sets import batch_write_input, MPRelaxSet structure = Structure.from_file("G:/Python/files/EntryWithCollCode418490.cif" ) #我们将首先从ICSD中发现的晶体学信息文件(CIF)中读取结构 print(structure) #目前我们所拥有的结构是无序的,并且Li的占有率跟成分不符合,需要调整 # loop over all sites in the structure在结构中所有的位置进行循环 for i, site in enumerate(structure): # change the occupancy of Li+ disordered sites to 0.5(也就是把结构矩阵中的Li+那一列调整为0.5) if not site.is_ordered: structure[i] = {"Li+": 0.5} print("The composition after adjustments is %s." % structure.composition.reduced_formula) #获得化学计量电荷平衡的L6PS5Cl。 #为了保持可排序的顺序,我们只在原始单元上执行枚举。原始单元可以使用空间群分析器获得 analyzer = SpacegroupAnalyzer(structure) prim_cell = analyzer.find_primitive() #找到原始单元,并且作为Structure对象返回 print(prim_cell) #我们将使用枚举结构结构转换类来枚举所有对称的不同结构。枚举结构是一个围绕枚举库的用户友好包装器,它是由HART等人编写的派生结构的FORTRAN库 enum = EnumerateStructureTransformation() enumerated = enum.apply_transformation( prim_cell, 100) # return no more than 100 structures #structures = [d["structure"] for d in enumerated] #print("%d structures returned." % len(structures))
#!/usr/bin/python3 from pymatgen import Structure from pymatgen.transformations.standard_transformations import OrderDisorderedStructureTransformation from pymatgen.transformations.advanced_transformations import EnumerateStructureTransformation from pymatgen.io.cif import CifWriter import sys try: cif_filename = sys.argv[1] except ValueError: print("please give the cif file name as the 1st argument!") s = Structure.from_file(cif_filename) prim = s.get_primitive_structure() # Merge sites that are less than 1A apart. prim.merge_sites(1) prim = prim.get_sorted_structure() t = EnumerateStructureTransformation() ordered = t.apply_transformation(prim, 5) print(len(ordered)) for i in range(len(ordered)): c = CifWriter(ordered[i]['structure'], symprec=0.01) c.write_file("LLZO_ordered-" + str(i) + ".cif")
def test_to_from_dict(self): trans = EnumerateStructureTransformation() d = trans.to_dict trans = EnumerateStructureTransformation.from_dict(d) self.assertEqual(trans.symm_prec, 0.1)