def get_unique_diffusion_pathways(structure: SymmetrizedStructure, dummy_atom: Element, site_i: int = -1, only_positive_direction=False, positive_weight=10, abreviated_search=1e6): if type(structure) != SymmetrizedStructure: try: sga = SpacegroupAnalyzer(structure, symprec=0.1) structure = sga.get_symmetrized_structure() except TypeError: sga = SpacegroupAnalyzer(structure, symprec=0.01) structure = sga.get_symmetrized_structure() equivalent_dummies = [ x for x in structure.equivalent_indices if structure[x[0]].specie == dummy_atom] all_combinations = itertools.product(*equivalent_dummies) # print(equivalent_dummies) combinations_to_check = np.prod([ float(len(x)) for x in equivalent_dummies]) if combinations_to_check > abreviated_search: print(combinations_to_check) new_eq_dummies = [ [] for _ in equivalent_dummies ] radius = 0.1 pt = structure.lattice.get_cartesian_coords([0.75,0.75,0.75]) while not all( new_eq_dummies ): sites_in_sphere = structure.get_sites_in_sphere(pt, radius, include_index=True, include_image=True) sites = [ i for _,_,i,image in sites_in_sphere if all(image == (0,0,0)) ] new_eq_dummies = [ [y for y in x if y in sites] for x in equivalent_dummies ] radius = radius + 0.1 equivalent_dummies = new_eq_dummies combinations_to_check = np.prod([float(len(x)) for x in equivalent_dummies]) if combinations_to_check > abreviated_search: equivalent_dummies = random.sample(equivalent_dummies, abreviated_search) print(combinations_to_check) best_sites = equivalent_dummies*2 + [[]] + [[]] best_pathway = None most_overlap = 0 best_weight = 9e9 path_count = 0 for dummy_is in all_combinations: # print(dummy_is) break_early = False path_count = path_count + 1 sites = {(site_i, (0,0,0)): 0} pathway = [] for i in dummy_is: neighbors = structure[i].properties['neighbors'].copy() image = structure[i].properties['image'] if only_positive_direction and (-1 in image or -2 in image): break_early = True break neighbors[0] = (neighbors[0], (0,0,0)) neighbors[1] = (neighbors[1], image) pathway.append(neighbors) for neighbor_i in neighbors: if neighbor_i in sites: sites[neighbor_i] = sites[neighbor_i] + 1 else: sites[neighbor_i] = 1 if only_positive_direction: if break_early: break_early = False continue cell_directions = [None,None,None] weight = 0 for _, direction in sites.keys(): # make sure directions are consistent for i, d in enumerate(direction): if d: # if it is in a cell outside unit if d > 0: weight = weight + 1 elif d < 0: weight = weight + positive_weight # if not cell_directions[i]: # haven't looked outside unit cell in this direction yet # cell_directions[i] = d # elif cell_directions[i] != d: # if the directions dont match # pass # break_early = True # break # else: # weight = weight - positive_weight # if break_early: # break # if break_early: # continue if len(sites) < len(best_sites) or (len(sites) == len(best_sites) and most_overlap < sites[(site_i, (0,0,0))]): if weight <= best_weight: best_sites = sites best_pathway = pathway most_overlap = sites[(site_i, (0,0,0))] best_weight = weight return best_pathway
def test_symmetrized_structure(self): t = OrderDisorderedStructureTransformation(symmetrized_structures=True) c = [] sp = [] c.append([0.5, 0.5, 0.5]) sp.append("Si4+") c.append([0.45, 0.45, 0.45]) sp.append({"Si4+": 0.5}) c.append([0.56, 0.56, 0.56]) sp.append({"Si4+": 0.5}) c.append([0.25, 0.75, 0.75]) sp.append({"Si4+": 0.5}) c.append([0.75, 0.25, 0.25]) sp.append({"Si4+": 0.5}) l = Lattice.cubic(5) s = Structure(l, sp, c) test_site = PeriodicSite("Si4+", c[2], l) s = SymmetrizedStructure(s, "not_real", [0, 1, 1, 2, 2], ["a", "b", "b", "c", "c"]) output = t.apply_transformation(s) self.assertTrue(test_site in output.sites)
def test_get_symmetrized_structure(self): symm_struct = self.sg.get_symmetrized_structure() for a in symm_struct.lattice.angles: self.assertEqual(a, 90) self.assertEqual(len(symm_struct.equivalent_sites), 5) symm_struct = self.disordered_sg.get_symmetrized_structure() self.assertEqual(len(symm_struct.equivalent_sites), 8) self.assertEqual([len(i) for i in symm_struct.equivalent_sites], [16, 4, 8, 4, 2, 8, 8, 8]) s1 = symm_struct.equivalent_sites[1][1] s2 = symm_struct[symm_struct.equivalent_indices[1][1]] self.assertEqual(s1, s2) self.assertEqual(self.sg4.get_symmetrized_structure()[0].magmom, 0.1) self.assertEqual(symm_struct.wyckoff_symbols[0], "16h") # self.assertEqual(symm_struct[0].wyckoff, "16h") # Check copying self.assertEqual(symm_struct.copy(), symm_struct) d = symm_struct.as_dict() from pymatgen.symmetry.structure import SymmetrizedStructure ss = SymmetrizedStructure.from_dict(d) self.assertEqual(ss.wyckoff_symbols[0], "16h") self.assertIn("SymmetrizedStructure", ss.__str__())