Exemple #1
0
def make_efnv_correction(charge: int,
                         calc_results: CalcResults,
                         perfect_calc_results: CalcResults,
                         dielectric_tensor: np.array,
                         accuracy: float = defaults.ewald_accuracy,
                         unit_conversion: float = 180.95128169876497):
    """
    Notes:
    (1) The formula written in YK2014 need to be divided by 4pi in the SI unit.
    (2) When assuming an element charge locate at the defect_coords and
        angstrom for length, relative dielectric tensor, Multiply
        elementary_charge * 1e10 / epsilon_0 = 180.95128169876497
        to make potential in V.
    """
    assert calc_results.structure.lattice == perfect_calc_results.structure.lattice

    structure_analyzer = DefectStructureAnalyzer(
        calc_results.structure, perfect_calc_results.structure)
    defect_coords = structure_analyzer.defect_center_coord
    lattice = calc_results.structure.lattice
    ewald = Ewald(lattice.matrix, dielectric_tensor, accuracy=accuracy)
    point_charge_correction = \
        0.0 if not charge else - ewald.lattice_energy * charge ** 2

    defect_region_radius = calc_max_sphere_radius(lattice.matrix)

    sites = []
    for d, p in structure_analyzer.atom_mapping.items():
        specie = str(calc_results.structure[d].specie)
        distance = structure_analyzer.distance_from_center(d)
        pot = calc_results.potentials[d] - perfect_calc_results.potentials[p]

        coord = calc_results.structure[d].frac_coords
        rel_coord = [x - y for x, y in zip(coord, defect_coords)]
        if distance <= defect_region_radius:
            pc_potential = None
        else:
            if charge == 0:
                pc_potential = 0
            else:
                pc_potential = ewald.atomic_site_potential(rel_coord) * charge
                pc_potential *= unit_conversion

        sites.append(PotentialSite(specie, distance, pot, pc_potential))

    return ExtendedFnvCorrection(
        charge=charge,
        point_charge_correction=point_charge_correction * unit_conversion,
        defect_region_radius=defect_region_radius,
        sites=sites,
        defect_coords=tuple(defect_coords))
def make_scene_dicts_json(parchg_list: List[str], calc_results: CalcResults,
                          perfect_calc_results: CalcResults, scene_level):
    structure_analyzer = DefectStructureAnalyzer(
        calc_results.structure, perfect_calc_results.structure)
    defect_pos = structure_analyzer.defect_center_coord
    scene_dicts = make_scene_dicts(parchg_list, defect_pos, level=scene_level)
    scene_dicts.to_json_file()
Exemple #3
0
def make_defect_entry(name: str, charge: int, perfect_structure: IStructure,
                      defect_structure: IStructure):

    analyzer = DefectStructureAnalyzer(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,
                       charge,
                       initial_structure,
                       None,
                       site_symmetry=symmetrizer.point_group,
                       defect_center=tuple(analyzer.defect_center_coord))
def structure_analyzer():
    cu2o_perfect = IStructure(Lattice.cubic(5),
                              species=["Cu"] * 4 + ["O"] * 2,
                              coords=[[0.25, 0.25, 0.25], [0.25, 0.74, 0.74],
                                      [0.75, 0.75, 0.25], [0.75, 0.25, 0.75],
                                      [0, 0, 0], [0.5, 0.5, 0.5]])

    # add [0.1, -0.1, 0]
    # 3rd -- 6th
    # [0.85, 0.65, 0.25] - [0.76, 0.73, 0.24] = [0.09, -0.08, 0.01]
    # [0.85, 0.15, 0.75] - [0.75, 0.25, 0.73] = [0.10, -0.10, 0.02]
    # [0.1, -0.1, 0] -[0.1, -0.1, 0] = [0, 0, 0]
    # [0.6, 0.4, 0.5] - [0.5, 0.5, 0.5] = [0.1, -0.1, 0]
    cu2o_defect = IStructure(
        Lattice.cubic(5),
        species=["Cu"] * 3 + ["O"] * 2 + ["H"],
        coords=[
            [0.25, 0.5, 0.5],  # defect
            [0.76, 0.73, 0.24],
            [0.75, 0.25, 0.73],
            [0.1, 0.9, 0],
            [0.5, 0.5, 0.5],
            [0.25] * 3
        ])  # defect

    return DefectStructureAnalyzer(defective_structure=cu2o_defect,
                                   perfect_structure=cu2o_perfect)
def test_neighboring_atom_indices(cubic_supercell):
    structure: Structure = cubic_supercell.copy()
    structure.pop(32)  # [0.25, 0, 0]
    structure.pop(0)  # [0, 0, 0]
    structure.append(species="Li", coords=[0.124, 0, 0])
    structure.to(filename="POSCAR")
    structure_analyzer = DefectStructureAnalyzer(structure, cubic_supercell)
    assert structure_analyzer.neighboring_atom_indices == sorted(
        [25, 15, 16, 23, 54, 47, 46, 56, 62])
def test_actual_files(vasp_files):
    d = vasp_files / "KInO2_Va_O_2"
    calc_results: CalcResults = loadfn(d / "Va_O1_2/calc_results.json")
    perfect_calc_results: CalcResults = loadfn(d / "perfect_calc_results.json")
    dsa = DefectStructureAnalyzer(calc_results.structure,
                                  perfect_calc_results.structure)
    a = list(range(192))
    a.pop(96)
    expected = dict(zip(range(191), a))
    assert dsa.inserted_indices == []
    assert dsa.vacancy_indices == [96]
    assert dsa.atom_mapping == expected
Exemple #7
0
def make_edge_characters(args):
    for d in args.dirs:
        logger.info(f"Parsing data in {d} ...")
        vasprun = Vasprun(d / defaults.vasprun)
        procar = Procar(d / defaults.procar)
        outcar = Outcar(d / defaults.outcar)
        calc_results = loadfn(d / "calc_results.json")
        structure_analyzer = DefectStructureAnalyzer(
            calc_results.structure, args.perfect_calc_results.structure)
        edge_characters = MakeEdgeCharacters(
            procar, vasprun, outcar,
            structure_analyzer.neighboring_atom_indices).edge_characters
        edge_characters.to_json_file(d / "edge_characters.json")
def structure_analyzer_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 DefectStructureAnalyzer(defective_structure=cu2o_defect,
                                   perfect_structure=cu2o_perfect)