def test_make_defect_energy_info(mocker): defect_entry = mocker.Mock(DefectEntry, autospec=True) defect_entry.name = "Va_Mg1" defect_entry.charge = -1 calc_results = mocker.Mock(CalcResults, autospec=True) calc_results.structure = IStructure(Lattice.cubic(1.0), ["O"], [[0.0]*3]) calc_results.energy = 10.0 calc_results.electronic_conv = False correction = mocker.Mock(Correction, autospec=True) correction.correction_dict = {"a": 10.0} p_calc_results = mocker.Mock(CalcResults, autospec=True) p_calc_results.structure = IStructure(Lattice.cubic(1.0), ["Mg", "O"], [[0.0]*3]*2) p_calc_results.energy = 1.0 standard_energies = StandardEnergies({"Mg": 10.0, "O": 20.0}) unitcell = mocker.Mock() unitcell.vbm = 100.0 actual = make_defect_energy_info(defect_entry, calc_results, correction, p_calc_results, standard_energies, unitcell) energy = DefectEnergy(formation_energy=10.0 - 1.0 + 10 - 100.0, energy_corrections={"a": 10.0}, is_shallow=None) expected = DefectEnergyInfo(name="Va_Mg1", charge=-1, atom_io={"Mg": -1}, defect_energy=energy) assert actual == expected
def test_make_calc_summary(mocker): defect_entry = mocker.Mock(spec=DefectEntry, autospec=True) defect_entry.name = "Va_O1" defect_entry.charge = 1 defect_entry.full_name = "Va_O1_1" calc_results = mocker.Mock(spec=CalcResults, autospec=True) calc_results.structure = \ IStructure(Lattice.cubic(1.0), ["Mg"], [[0.0]*3]) calc_results.energy = 10.0 + defaults.abs_strange_energy - 0.1 structure_info = mocker.Mock(spec=DefectStructureInfo, autospec=True) p_calc_results = mocker.Mock(spec=CalcResults, autospec=True) p_calc_results.structure = \ IStructure(Lattice.cubic(1.0), ["Mg", "O"], [[0.0]*3]*2) p_calc_results.energy = 10.0 actual = make_calc_summary(calc_set=[(calc_results, defect_entry, structure_info)], p_calc_results=p_calc_results) single_summary = SingleCalcSummary( charge=1, atom_io={"O": -1}, electronic_conv=calc_results.electronic_conv, ionic_conv=calc_results.ionic_conv, is_energy_strange=False, same_config_from_init=structure_info.same_config_from_init, defect_type=str(structure_info.defect_type), symm_relation=str(structure_info.symm_relation)) expected = CalcSummary({"Va_O1_1": single_summary}) assert actual == expected
def structure_comparator(): cu2o_perfect = IStructure( Lattice.cubic(5), species=["Cu"] * 4 + ["O"] * 2, coords=[ [0.25, 0.25, 0.25], # removed [0.25, 0.74, 0.74], # removed [0.75, 0.75, 0.25], [0.75, 0.25, 0.75], [0, 0, 0], [0.5, 0.5, 0.5] ]) cu2o_defect = IStructure( Lattice.cubic(5), species=["Cu"] * 3 + ["O"] * 2 + ["H"], coords=[ [0.25, 0.5, 0.5], # inserted [0.76, 0.73, 0.24], [0.75, 0.25, 0.73], [0.05, 0.95, 0], [0.5, 0.5, 0.5], [0.25] * 3 ]) # inserted return DefectStructureComparator(defect_structure=cu2o_defect, perfect_structure=cu2o_perfect)
def test_make_defect_entry(defect_entry): relaxed_coords = \ [[0.25, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 0.51], [0.0, 0.51, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.5]] relaxed_defect = IStructure(Lattice.cubic(10.0), ["Li"] + ["H"] * 3 + ["He"] * 4, relaxed_coords) unrelaxed_coords = \ [[0.25, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.5]] unrelaxed_defect = IStructure(Lattice.cubic(10.0), ["Li"] + ["H"] * 3 + ["He"] * 4, unrelaxed_coords) actual = make_defect_entry(name="Va_O1", charge=1, perfect_structure=perfect, defect_structure=relaxed_defect) expected = DefectEntry(name="Va_O1", charge=1, structure=unrelaxed_defect, perturbed_structure=None, site_symmetry="4mm", defect_center=(0.125, 0.0, 0.0)) assert actual == expected
def structure_comparator_periodic_issue(): cu2o_perfect = IStructure(Lattice.cubic(5), species=["Cu"] * 4 + ["O"] * 2, coords=[[0.25, 0.25, 0.25], [0.25, 0.75, 0.75], [0.75, 0.75, 0.25], [0.75, 0.25, 0.75], [0, 0, 0], [0.5, 0.5, 0.5]]) # defect center is ([1.0, 1.0, 1.0] + [0.99, 0.99, 0.99]) / 2 = [0.995]*3 cu2o_defect = IStructure(Lattice.cubic(5), species=["Cu"] * 4 + ["O"] + ["H"], coords=[[0.25, 0.25, 0.25], [0.25, 0.75, 0.75], [0.75, 0.75, 0.25], [0.75, 0.25, 0.75], [0.5, 0.5, 0.5], [0.99, 0.99, 0.99]]) return DefectStructureComparator(defect_structure=cu2o_defect, perfect_structure=cu2o_perfect)
def simple_cubic_2x2x2(): lattice = Lattice.cubic(2.0) coords = [[0.0, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.5]] return IStructure(lattice=lattice, species=["H"] * 8, coords=coords)
def test_supercell_input(self): multi = [2, 1, 1] supercell = Supercell(structure=self.mgo64_struct, trans_mat=multi, check_unitcell=True) supercell.to("POSCAR") os.remove("POSCAR") os.remove("UPOSCAR") actual = supercell.structure expected = IStructure.from_str( """trans_mat: [3.9999999999999996, 0.0, 0.0, 0.0, 1.9999999999999998, 0.0, 0.0, 0.0, 1.9999999999999998], multi: 16, isotropy: (0.5333, 59.99999999999999) 1.0 0.000000 6.314592 6.314592 2.104864 0.000000 2.104864 2.104864 2.104864 0.000000 Mg O 3 3 direct 0.000000 0.000000 0.000000 Mg 0.333333 0.000000 0.000000 Mg 0.666667 0.000000 -0.000000 Mg 0.166667 0.500000 0.500000 O 0.500000 0.500000 0.500000 O 0.833333 0.500000 0.500000 O""", fmt="poscar") self.assertEqual(expected, actual)
def complex_monoclinic(): lattice = Lattice.monoclinic(3, 4, 5, 100) coords = [[0.0, 0.0, 0.0], [0.1, 0.0, 0.0], [0.9, 0.0, 0.0], [0.2, 0.0, 0.0], [0.8, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H", "He", "He", "He", "He"], coords=coords)
def test_recommended_supercell_conv(self): supercells_mgo = Supercells(self.mgo_struct, conventional_base=True, max_num_atoms=500, min_num_atoms=1, criterion=1.1) supercell_mgo = supercells_mgo.sorted_supercells_by_num_atoms[0] actual = supercell_mgo.structure supercell_mgo.to("POSCAR-MgO") os.remove("POSCAR-MgO") expected = IStructure.from_str( """trans_mat: -1 1 1 1 -1 1 1 1 -1, multi: 4.0, isotropy: 0.0 1.0 4.246894 0.000000 0.000000 0.000000 4.246894 0.000000 0.000000 0.000000 4.246894 Mg O 4 4 direct 0.000000 0.000000 0.000000 Mg 0.500000 0.500000 0.000000 Mg 0.500000 0.000000 0.500000 Mg 0.000000 0.500000 0.500000 Mg 0.500000 0.500000 0.500000 O 1.000000 1.000000 0.500000 O 1.000000 0.500000 1.000000 O 0.500000 1.000000 1.000000 O""", fmt="poscar") self.assertEqual(expected, actual)
def calc_results(): return CalcResults(structure=IStructure(Lattice.cubic(1.0), ["H"], [[0.0] * 3]), energy=1.0, magnetization=0.0, potentials=[0.0], electronic_conv=False, ionic_conv=False)
def test_make_recommended_supercell(simple_cubic, simple_cubic_2x2x2, tmpdir): tmpdir.chdir() args = Namespace(unitcell=simple_cubic, matrix=None, min_num_atoms=8, max_num_atoms=8) make_supercell(args) info = loadfn("supercell_info.json") assert IStructure.from_file("SPOSCAR") == simple_cubic_2x2x2 assert info.structure == simple_cubic_2x2x2 assert info.transformation_matrix == [[2, 0, 0], [0, 2, 0], [0, 0, 2]]
def test_make_efnv_correction(mocker): mock_perfect = mocker.Mock(spec=CalcResults, autospec=True) mock_defect = mocker.Mock(spec=CalcResults, autospec=True) mock_perfect.structure = IStructure(Lattice.cubic(10), species=["H"] + ["He"] * 3 + ["Li"], coords=[[0, 0, 0], [1 / 2, 1 / 2, 0], [1 / 2, 0, 1 / 2], [0, 1 / 2, 1 / 2], [0, 0, 1 / 2]]) mock_defect.structure = IStructure(Lattice.cubic(10), species=["He"] * 3 + ["Li"], coords=[[1 / 2, 1 / 2, 0], [1 / 2, 0, 1 / 2], [0, 1 / 2, 1 / 2], [0, 0, 1 / 2]]) mock_perfect.potentials = [3.0, 4.0, 5.0, 6.0, 7.0] mock_defect.potentials = [14.0, 25.0, 36.0, 47.0] mock_ewald = mocker.patch("pydefect.cli.vasp.make_efnv_correction.Ewald") ewald = mocker.Mock() ewald.lattice_energy = 1e3 ewald.atomic_site_potential.return_value = 1e4 mock_ewald.return_value = ewald efnvc = make_efnv_correction(charge=2, calc_results=mock_defect, perfect_calc_results=mock_perfect, dielectric_tensor=np.eye(3)) unit_conversion = 180.95128169876497 assert efnvc.charge == 2 assert efnvc.point_charge_correction == -4e3 * unit_conversion assert efnvc.defect_region_radius == 5.0 assert efnvc.sites == [ PotentialSite("He", 5 * np.sqrt(2), 10.0, 2e4 * unit_conversion), PotentialSite("He", 5 * np.sqrt(2), 20.0, 2e4 * unit_conversion), PotentialSite("He", 5 * np.sqrt(2), 30.0, 2e4 * unit_conversion), PotentialSite("Li", 5.0, 40.0, None), ]
def test_make_supercell_from_matrix(simple_cubic, simple_cubic_2x1x1, tmpdir): tmpdir.chdir() matrix = [2, 1, 1] args = Namespace(unitcell=simple_cubic, matrix=matrix, min_num_atoms=None, max_num_atoms=None) make_supercell(args) info = loadfn("supercell_info.json") assert IStructure.from_file("SPOSCAR") == simple_cubic_2x1x1 assert info.structure == simple_cubic_2x1x1 assert info.transformation_matrix == [[2, 0, 0], [0, 1, 0], [0, 0, 1]]
def ortho_conventional(): lattice = Lattice.orthorhombic(5, 6, 7) coords = [ [0.0, 0.0, 0.0], [0.5, 0.5, 0.0], [0.5, 0.0, 0.5], [0.0, 0.5, 0.5], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.5], ] return IStructure(lattice=lattice, species=["H"] * 4 + ["He"] * 4, coords=coords)
def test_init1(self): multi = [2, 1, 1] actual = Supercell(structure=self.mgo_struct, trans_mat=multi, multiplicity=2).structure expected = IStructure.from_str("""Mg2 O2 1.0 0.000000 4.246894 4.246894 2.123447 0.000000 2.123447 2.123447 2.123447 0.000000 Mg O 2 2 direct 0.000000 0.000000 0.000000 Mg 0.500000 0.000000 0.000000 Mg 0.250000 0.500000 0.500000 O 0.750000 0.500000 0.500000 O""", fmt="poscar") self.assertEqual(expected, actual)
def setUpClass(cls): coords = [[0, 0, 0], [0.75, 0.5, 0.75]] lattice = Lattice([[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]]) cls.struct_si = IStructure(lattice, ["Si"] * 2, coords) cls.ref_incar = Incar.from_file( os.path.join(module_dir, "..", "test_files", "setup_test", "INCAR")) cls.ref_poscar = Poscar.from_file( os.path.join(module_dir, "..", "test_files", "setup_test", "POSCAR")) cls.ref_potcar = Potcar.from_file( os.path.join(module_dir, "..", "test_files", "setup_test", "POTCAR")) cls.ref_kpoints = Kpoints.from_file( os.path.join(module_dir, "..", "test_files", "setup_test", "KPOINTS"))
def test_make_site_diff_wo_diff(): s1 = IStructure(Lattice.cubic(10), species=["H"], coords=[[0] * 3]) s2 = s1.copy() structure_comparator = DefectStructureComparator(s1, s2) site_diff = structure_comparator.make_site_diff() assert site_diff == SiteDiff([], [], [], []) assert site_diff.is_no_diff s1 = IStructure(Lattice.cubic(10), species=["H", "He"], coords=[[0] * 3, [0.5] * 3]) s2 = IStructure(Lattice.cubic(10), species=["H"], coords=[[0] * 3]) structure_comparator = DefectStructureComparator(defect_structure=s2, perfect_structure=s1) site_diff = structure_comparator.make_site_diff() assert site_diff == SiteDiff([(1, "He", (0.5, 0.5, 0.5))], [], [], []) assert site_diff.is_no_diff is False
def test_init2(self): multi = [[-1, 1, 1], [1, -1, 1], [1, 1, -1]] actual = Supercell(structure=self.mgo_struct, trans_mat=multi, multiplicity=4).structure expected = IStructure.from_str("""Mg4 O4 1.0 4.246894 0.000000 0.000000 0.000000 4.246894 0.000000 0.000000 0.000000 4.246894 Mg O 4 4 direct 0.000000 0.000000 0.000000 Mg 0.500000 0.500000 0.000000 Mg 0.500000 0.000000 0.500000 Mg 0.000000 0.500000 0.500000 Mg 0.500000 0.500000 0.500000 O 1.000000 1.000000 0.500000 O 1.000000 0.500000 1.000000 O 0.500000 1.000000 1.000000 O""", fmt="poscar") self.assertEqual(expected, actual)
def test_recommended_supercell(self): supercells_mgo = Supercells(self.mgo_struct, conventional_base=False, max_num_atoms=500, min_num_atoms=16, criterion=1.1) supercell_mgo = supercells_mgo.sorted_supercells_by_num_atoms[0] actual = supercell_mgo.structure expected = IStructure.from_str("""Mg8 O8 1.0 0.000000 4.246894 4.246894 4.246894 0.000000 4.246894 4.246894 4.246894 0.000000 Mg O 8 8 direct 0.000000 0.000000 0.000000 Mg 0.000000 0.000000 0.500000 Mg 0.000000 0.500000 0.000000 Mg 0.000000 0.500000 0.500000 Mg 0.500000 0.000000 0.000000 Mg 0.500000 0.000000 0.500000 Mg 0.500000 0.500000 0.000000 Mg 0.500000 0.500000 0.500000 Mg 0.250000 0.250000 0.250000 O 0.250000 0.250000 0.750000 O 0.250000 0.750000 0.250000 O 0.250000 0.750000 0.750000 O 0.750000 0.250000 0.250000 O 0.750000 0.250000 0.750000 O 0.750000 0.750000 0.250000 O 0.750000 0.750000 0.750000 O""", fmt="poscar") self.assertEqual(expected, actual) actual_comment = supercell_mgo.comment expected_comment = "trans_mat: [2, 0, 0, 0, 2, 0, 0, 0, 2], multi: 8, isotropy: (0.0, 60.0)" self.assertEqual(expected_comment, actual_comment)
def make_defect_entry(name: str, charge: int, perfect_structure: IStructure, defect_structure: IStructure): analyzer = DefectStructureComparator(perfect_structure, defect_structure) species = [] frac_coords = [] for d, p in enumerate(analyzer.p_to_d): if p is None: site = defect_structure[d] else: site = perfect_structure[p] species.append(site.specie) frac_coords.append(site.frac_coords) initial_structure = IStructure(perfect_structure.lattice, species, frac_coords) symmetrizer = StructureSymmetrizer(initial_structure) return DefectEntry(name=name, charge=charge, structure=initial_structure, site_symmetry=symmetrizer.point_group, defect_center=tuple(analyzer.defect_center_coord))
def test_num_atom_diff(): s1 = IStructure(Lattice.cubic(1), ["H", "He"], [[0] * 3] * 2) s2 = IStructure(Lattice.cubic(1), ["H", "Li"], [[0] * 3] * 2) assert num_atom_differences(s1, s2) == {"He": 1, "Li": -1}
def bcc(): lattice = Lattice.cubic(1.0) coords = [[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]] return IStructure(lattice=lattice, species=["H"] * 2, coords=coords)
def tetra_close_to_cubic(): lattice = Lattice.tetragonal(1.001 * 10 / sqrt(2), 10) coords = [[0.0, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H"], coords=coords)
def c_centered_monoclinic(): lattice = Lattice.monoclinic(3, 4, 5, 100) coords = [[0.0, 0.0, 0.0], [0.5, 0.5, 0.0]] return IStructure(lattice=lattice, species=["H", "H"], coords=coords)
def a_centered_orthorhombic(): lattice = Lattice([[1, 0, 0], [0, 2, 3], [0, -2, 3]]) coords = [[0.5, 0.8, 0.8], [0.0, 0.3, 0.0], [0.0, 0.0, 0.3]] return IStructure(lattice=lattice, species=["H"] * 3, coords=coords)
def elongated_tetragonal(): lattice = Lattice.tetragonal(a=1, c=3 * sqrt(2)) coords = [[0.0, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H"], coords=coords)
def rhombohedral(): lattice = Lattice.rhombohedral(a=1, alpha=45) coords = [[0.0, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H"], coords=coords)
def simple_cubic(): lattice = Lattice.cubic(1.0) coords = [[0.0, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H"], coords=coords)
def simple_cubic_2x1x1(): lattice = Lattice.orthorhombic(2.0, 1.0, 1.0) coords = [[0.0, 0.0, 0.0], [0.5, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H", "H"], coords=coords)
def monoclinic(): lattice = Lattice.monoclinic(3, 4, 5, 100) coords = [[0.0, 0.0, 0.0]] return IStructure(lattice=lattice, species=["H"], coords=coords)