def test_local_extrema_append_sites_to_supercell_info(local_extrema, simple_cubic): sites = { "H1": Site(element="H", wyckoff_letter="a", site_symmetry="mmm", equivalent_atoms=[0, 1, 2, 3, 4, 5, 6, 7]) } actual_cubic = Structure.from_dict(simple_cubic.as_dict()) supercell_info = SupercellInfo(actual_cubic * [2, 2, 2], "Pm-3m", [[2, 0, 0], [0, 2, 0], [0, 0, 2]], sites, []) actual = local_extrema.append_sites_to_supercell_info(supercell_info, indices=[1, 2]) interstitials = [ Interstitial(frac_coords=[0.05] * 3, site_symmetry="3m", info="test #1"), Interstitial(frac_coords=[0.05, 0.0, 0.0], site_symmetry="4mm", info="test #2") ] expected = SupercellInfo(actual_cubic * [2, 2, 2], "Pm-3m", [[2, 0, 0], [0, 2, 0], [0, 0, 2]], sites, interstitials) assert actual == expected
def append_interstitial(supercell_info: SupercellInfo, unitcell_structure: Union[Structure, IStructure], frac_coords: List[Union[List[float], Coords]], infos: List[str]) -> SupercellInfo: """ inv_trans_mat must be multiplied with coords from the right as the trans_mat is multiplied to the unitcell lattice vector from the left. see __mul__ of IStructure in pymatgen. x_u, x_s means the frac coordinates in unitcell and supercell, while a, b, c are the unitcell lattice vector. (a_u, b_u, c_u) . (a, b, c) = (a_s, b_s, c_s) . trans_mat . (a, b, c) (a_u, b_u, c_u) = (a_s, b_s, c_s) . trans_mat so, (a_s, b_s, c_s) = (a_u, b_u, c_u) . inv_trans_ma """ if supercell_info.unitcell_structure and \ supercell_info.unitcell_structure != unitcell_structure: raise NotPrimitiveError if isinstance(frac_coords[0], float): frac_coords = [frac_coords] for fcoord, info in zip(frac_coords, infos): us = Structure.from_dict(unitcell_structure.as_dict()) us.append(species=Element.H, coords=fcoord) symmetrizer = StructureSymmetrizer(us) site_symm = symmetrizer.spglib_sym_data["site_symmetry_symbols"][-1] inv_matrix = inv(np.array(supercell_info.transformation_matrix)) new_coords = np.dot(fcoord, inv_matrix).tolist() supercell_info.interstitials.append( Interstitial(frac_coords=new_coords, site_symmetry=site_symm, info=info)) return supercell_info
def append_interstitial(supercell_info: SupercellInfo, unitcell_structure: Structure, frac_coords: List[float]) -> SupercellInfo: """ inv_trans_mat must be multiplied with coords from the right as the trans_mat is multiplied to the unitcell lattice vector from the left. see __mul__ of IStructure in pymatgen. x_u, x_s means the frac coordinates in unitcell and supercell, while a, b, c are the unitcell lattice vector. (a_u, b_u, c_u) . (a, b, c) = (a_s, b_s, c_s) . trans_mat . (a, b, c) (a_u, b_u, c_u) = (a_s, b_s, c_s) . trans_mat so, (a_s, b_s, c_s) = (a_u, b_u, c_u) . inv_trans_mat """ if supercell_info.unitcell_structure and \ supercell_info.unitcell_structure != unitcell_structure: raise NotPrimitiveError unitcell_structure.append(species=Element.H, coords=frac_coords) symmetrizer = StructureSymmetrizer(unitcell_structure) wyckoff_letter = (symmetrizer.spglib_sym_data["wyckoffs"][-1]) site_symmetry = (symmetrizer.spglib_sym_data["site_symmetry_symbols"][-1]) inv_matrix = inv(np.array(supercell_info.transformation_matrix)) new_coords = np.dot(frac_coords, inv_matrix).tolist() supercell_info.interstitials.append( Interstitial(frac_coords=new_coords, wyckoff_letter=wyckoff_letter, site_symmetry=site_symmetry)) return supercell_info
def test_add_interstitial(cubic_supercell_info_wo_int): primitive = Structure(Lattice.rhombohedral(7.071068, 60), species=["H", "He"], coords=[[0.0] * 3, [0.5] * 3]) new_supercell_info = append_interstitial(cubic_supercell_info_wo_int, primitive, [1 / 4, 1 / 4, 1 / 4]) expected = Interstitial(frac_coords=[1 / 8, 1 / 8, 1 / 8], wyckoff_letter="d", site_symmetry="-43m") assert new_supercell_info.interstitials[0] == expected
def cubic_supercell_info(cubic_supercell): sites = {"H1": Site(element="H", wyckoff_letter="a", site_symmetry="m-3m", equivalent_atoms=list(range(32))), "He1": Site(element="He", wyckoff_letter="b", site_symmetry="m-3m", equivalent_atoms=list(range(32, 64)))} interstitial = Interstitial([0.25]*3, site_symmetry="yy") return SupercellInfo(cubic_supercell, "Fm-3m", [[2, 0, 0], [0, 2, 0], [0, 0, 2]], sites, interstitials=[interstitial])
def test_add_interstitial2(mocker, simple_cubic): mock_supercell_info = mocker.Mock() mock_supercell_info.unitcell_structure = simple_cubic mock_supercell_info.transformation_matrix = [[2, 0, 0], [0, 2, 0], [0, 0, 2]] mock_supercell_info.interstitials = [] unitcell = Structure.from_dict(simple_cubic.as_dict()) new_supercell_info = append_interstitial(mock_supercell_info, unitcell, [(0.0, 0.0, 0.1)], infos=["test1"]) expected = Interstitial(frac_coords=[0.0, 0.0, 0.05], site_symmetry="4mm", info="test1") assert new_supercell_info.interstitials[0] == expected
def supercell_info(ortho_conventional): sites = { "H1": Site(element="H", wyckoff_letter="a", site_symmetry="mmm", equivalent_atoms=[0, 1, 2, 3]), "He1": Site(element="He", wyckoff_letter="b", site_symmetry="mmm", equivalent_atoms=[4, 5, 6, 7]) } interstitial = Interstitial(frac_coords=[0.25] * 3, site_symmetry="yy", info="test") return SupercellInfo(ortho_conventional, "Fmmm", [[1, 0, 0], [0, 1, 0], [0, 0, 1]], sites, [interstitial])
def supercell_info(mocker, ortho_conventional): mock = mocker.patch("pydefect.util.structure_tools.defaults") mock.same_distance_criterion = defaults.same_distance_criterion mock.cutoff_distance_factor = 1.7 sites = { "H1": Site(element="H", wyckoff_letter="a", site_symmetry="mmm", equivalent_atoms=[0, 1, 2, 3]), "He1": Site(element="He", wyckoff_letter="b", site_symmetry="mmm", equivalent_atoms=[4, 5, 6, 7]) } interstitial = Interstitial([0.25] * 3, wyckoff_letter="x", site_symmetry="yy") return SupercellInfo(ortho_conventional, "Fmmm", [[1, 0, 0], [0, 1, 0], [0, 0, 1]], sites, [interstitial])
def interstitial(): return Interstitial(frac_coords=[0.25, 0.25, 0.25], wyckoff_letter="a", site_symmetry="m3m")