コード例 #1
0
ファイル: vasp.py プロジェクト: Johnson-Wang/phonopy
def get_born_OUTCAR(poscar_filename="POSCAR",
                    outcar_filename="OUTCAR",
                    primitive_axis=np.eye(3),
                    is_symmetry=True,
                    symmetrize_tensors=False):
    cell = read_vasp(poscar_filename)
    primitive = Primitive(cell, primitive_axis)
    p2p = primitive.get_primitive_to_primitive_map()
    symmetry = Symmetry(primitive, is_symmetry=is_symmetry)
    independent_atoms = symmetry.get_independent_atoms()
    prim_lat = primitive.get_cell().T
    outcar = open(outcar_filename)
    
    borns = []
    while True:
        line = outcar.readline()
        if not line:
            break
    
        if "NIONS" in line:
            num_atom = int(line.split()[11])
    
        if "MACROSCOPIC STATIC DIELECTRIC TENSOR" in line:
            epsilon = []
            outcar.readline()
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])
    
        if "BORN" in line:
            outcar.readline()
            line = outcar.readline()
            if "ion" in line:
                for i in range(num_atom):
                    born = []
                    born.append([float(x) for x in outcar.readline().split()][1:])
                    born.append([float(x) for x in outcar.readline().split()][1:])
                    born.append([float(x) for x in outcar.readline().split()][1:])
                    outcar.readline()
                    borns.append(born)


    reduced_borns = []
    for p_i, u_i in enumerate(p2p):
        if p_i in independent_atoms:
            if symmetrize_tensors:
                site_sym = [similarity_transformation(prim_lat, rot)
                            for rot in symmetry.get_site_symmetry(p_i)]
                reduced_borns.append(symmetrize_tensor(borns[u_i], site_sym))
            else:
                reduced_borns.append(borns[u_i])
                
    if symmetrize_tensors:
        point_sym = [similarity_transformation(prim_lat, rot)
                     for rot in symmetry.get_pointgroup_operations()]
        epsilon = symmetrize_tensor(epsilon, point_sym)
    else:
        epsilon = np.array(epsilon)

    return np.array(reduced_borns), epsilon
コード例 #2
0
def get_born_OUTCAR(poscar_filename="POSCAR",
                    outcar_filename="OUTCAR",
                    primitive_axis=np.eye(3),
                    is_symmetry=True,
                    symmetrize_tensors=False):
    cell = read_vasp(poscar_filename)
    primitive = Primitive(cell, primitive_axis)
    p2p = primitive.get_primitive_to_primitive_map()
    symmetry = Symmetry(primitive, is_symmetry=is_symmetry)
    independent_atoms = symmetry.get_independent_atoms()
    prim_lat = primitive.get_cell().T
    outcar = open(outcar_filename)

    borns = []
    while True:
        line = outcar.readline()
        if not line:
            break

        if "NIONS" in line:
            num_atom = int(line.split()[11])

        if "MACROSCOPIC STATIC DIELECTRIC TENSOR" in line:
            epsilon = []
            outcar.readline()
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])

        if "BORN" in line:
            outcar.readline()
            line = outcar.readline()
            if "ion" in line:
                for i in range(num_atom):
                    born = []
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    outcar.readline()
                    borns.append(born)

    reduced_borns = []
    for p_i, u_i in enumerate(p2p):
        if p_i in independent_atoms:
            if symmetrize_tensors:
                site_sym = [
                    similarity_transformation(prim_lat, rot)
                    for rot in symmetry.get_site_symmetry(p_i)
                ]
                reduced_borns.append(symmetrize_tensor(borns[u_i], site_sym))
            else:
                reduced_borns.append(borns[u_i])

    if symmetrize_tensors:
        point_sym = [
            similarity_transformation(prim_lat, rot)
            for rot in symmetry.get_pointgroup_operations()
        ]
        epsilon = symmetrize_tensor(epsilon, point_sym)
    else:
        epsilon = np.array(epsilon)

    return np.array(reduced_borns), epsilon
コード例 #3
0
ファイル: fc3.py プロジェクト: phonopy/phono3py
def _get_fc3_done(supercell: PhonopyAtoms, disp_dataset, symmetry: Symmetry,
                  array_shape):
    num_atom = len(supercell)
    fc3_done = np.zeros(array_shape, dtype="byte")
    symprec = symmetry.tolerance
    lattice = supercell.cell.T
    positions = supercell.scaled_positions
    rotations = symmetry.symmetry_operations["rotations"]
    translations = symmetry.symmetry_operations["translations"]

    atom_mapping = []
    for rot, trans in zip(rotations, translations):
        atom_indices = [
            _get_atom_by_symmetry(lattice, positions, rot, trans, i, symprec)
            for i in range(num_atom)
        ]
        atom_mapping.append(atom_indices)

    for dataset_first_atom in disp_dataset["first_atoms"]:
        first_atom_num = dataset_first_atom["number"]
        site_symmetry = symmetry.get_site_symmetry(first_atom_num)
        direction = np.dot(dataset_first_atom["displacement"],
                           np.linalg.inv(supercell.cell))
        reduced_site_sym = get_reduced_site_symmetry(site_symmetry, direction,
                                                     symprec)
        least_second_atom_nums = []
        for second_atoms in dataset_first_atom["second_atoms"]:
            if "included" in second_atoms:
                if second_atoms["included"]:
                    least_second_atom_nums.append(second_atoms["number"])
            elif "cutoff_distance" in disp_dataset:
                min_vec = get_smallest_vector_of_atom_pair(
                    first_atom_num, second_atoms["number"], supercell, symprec)
                min_distance = np.linalg.norm(np.dot(lattice, min_vec))
                if "pair_distance" in second_atoms:
                    assert abs(min_distance -
                               second_atoms["pair_distance"]) < 1e-4
                if min_distance < disp_dataset["cutoff_distance"]:
                    least_second_atom_nums.append(second_atoms["number"])

        positions_shifted = positions - positions[first_atom_num]
        least_second_atom_nums = np.unique(least_second_atom_nums)

        for red_rot in reduced_site_sym:
            second_atom_nums = [
                _get_atom_by_symmetry(
                    lattice,
                    positions_shifted,
                    red_rot,
                    np.zeros(3, dtype="double"),
                    i,
                    symprec,
                ) for i in least_second_atom_nums
            ]
        second_atom_nums = np.unique(second_atom_nums)

        for i in range(len(rotations)):
            rotated_atom1 = atom_mapping[i][first_atom_num]
            for j in second_atom_nums:
                fc3_done[rotated_atom1, atom_mapping[i][j]] = 1

    return fc3_done
コード例 #4
0
ファイル: vasp.py プロジェクト: arbegla/phonopy
def get_born_OUTCAR(poscar_filename="POSCAR",
                    outcar_filename="OUTCAR",
                    primitive_axis=np.eye(3),
                    supercell_matrix=np.eye(3, dtype='intc'),
                    is_symmetry=True,
                    symmetrize_tensors=False):
    ucell = read_vasp(poscar_filename)
    scell = get_supercell(ucell, supercell_matrix)
    inv_smat = np.linalg.inv(supercell_matrix)
    pcell = get_primitive(scell, np.dot(inv_smat, primitive_axis))
    u_sym = Symmetry(ucell, is_symmetry=is_symmetry)
    p_sym = Symmetry(pcell, is_symmetry=is_symmetry)
    lattice = ucell.get_cell().T
    outcar = open(outcar_filename)
    
    borns = []
    while True:
        line = outcar.readline()
        if not line:
            break
    
        if "NIONS" in line:
            num_atom = int(line.split()[11])
    
        if "MACROSCOPIC STATIC DIELECTRIC TENSOR" in line:
            epsilon = []
            outcar.readline()
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])
            epsilon.append([float(x) for x in outcar.readline().split()])
    
        if "BORN" in line:
            outcar.readline()
            line = outcar.readline()
            if "ion" in line:
                for i in range(num_atom):
                    born = []
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    born.append([float(x)
                                 for x in outcar.readline().split()][1:])
                    outcar.readline()
                    borns.append(born)

    borns = np.array(borns, dtype='double')
    epsilon = np.array(epsilon, dtype='double')
    if symmetrize_tensors:
        borns_orig = borns.copy()
        point_sym = [similarity_transformation(lattice, r)
                     for r in u_sym.get_pointgroup_operations()]
        epsilon = symmetrize_tensor(epsilon, point_sym)
        for i in range(num_atom):
            z = borns[i]
            site_sym = [similarity_transformation(lattice, r)
                        for r in u_sym.get_site_symmetry(i)]
            borns[i] = symmetrize_tensor(z, site_sym)

        rotations = u_sym.get_symmetry_operations()['rotations']
        map_atoms = u_sym.get_map_atoms()
        borns_copy = np.zeros_like(borns)
        for i, m_i in enumerate(map_atoms):
            count = 0
            for j, r_j in enumerate(u_sym.get_map_operations()):
                if map_atoms[j] == m_i:
                    count += 1
                    r_cart = similarity_transformation(lattice, rotations[r_j])
                    borns_copy[i] += similarity_transformation(r_cart, borns[j])
            borns_copy[i] /= count

        borns = borns_copy
        sum_born = borns.sum(axis=0) / len(borns)
        borns -= sum_born

        if (np.abs(borns_orig - borns) > 0.1).any():
            sys.stderr.write(
                "Born effective charge symmetrization might go wrong.\n")
        
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc')
    s_indep_atoms = p2s[p_sym.get_independent_atoms()]
    u2u = scell.get_unitcell_to_unitcell_map()
    u_indep_atoms = [u2u[x] for x in s_indep_atoms]
    reduced_borns = borns[u_indep_atoms].copy()

    return reduced_borns, epsilon
コード例 #5
0
ファイル: displacement_fc3.py プロジェクト: phonopy/phono3py
def get_third_order_displacements(cell: PhonopyAtoms,
                                  symmetry: Symmetry,
                                  is_plusminus="auto",
                                  is_diagonal=False):
    """Create dispalcement dataset.

    Note
    ----
    Atoms 1, 2, and 3 are defined as follows:

    Atom 1: The first displaced atom. Third order force constant
            between Atoms 1, 2, and 3 is calculated.
    Atom 2: The second displaced atom. Second order force constant
            between Atoms 2 and 3 is calculated.
    Atom 3: Force is mesuared on this atom.

    Parameters
    ----------
    cell : PhonopyAtoms
        Supercell
    symmetry : Symmetry
        Symmetry of supercell
    is_plusminus : str or bool, optional
        Type of displacements, plus only (False), always plus and minus (True),
        and plus and minus depending on site symmetry ('auto').
    is_diagonal : bool, optional
        Whether allow diagonal displacements of Atom 2 or not

    Returns
    -------
    [{'number': atom1,
      'direction': [1, 0, 0],  # int
      'second_atoms': [ {'number': atom2,
                         'directions': [ [1, 0, 0], [-1, 0, 0], ... ]
                         'distance': distance-between-atom1-and-atom2},
                        {'number': ... }, ... ] },
     {'number': atom1, ... } ]

    """
    positions = cell.scaled_positions
    lattice = cell.cell.T

    # Least displacements of first atoms (Atom 1) are searched by
    # using respective site symmetries of the original crystal.
    # 'is_diagonal=False' below is made intentionally to expect
    # better accuracy.
    disps_first = get_least_displacements(symmetry,
                                          is_plusminus=is_plusminus,
                                          is_diagonal=False)

    symprec = symmetry.tolerance

    dds = []
    for disp in disps_first:
        atom1 = disp[0]
        disp1 = disp[1:4]
        site_sym = symmetry.get_site_symmetry(atom1)

        dds_atom1 = {"number": atom1, "direction": disp1, "second_atoms": []}

        # Reduced site symmetry at the first atom with respect to
        # the displacement of the first atoms.
        reduced_site_sym = get_reduced_site_symmetry(site_sym, disp1, symprec)
        # Searching orbits (second atoms) with respect to
        # the first atom and its reduced site symmetry.
        second_atoms = get_least_orbits(atom1, cell, reduced_site_sym, symprec)

        for atom2 in second_atoms:
            dds_atom2 = _get_next_displacements(atom1, atom2, reduced_site_sym,
                                                lattice, positions, symprec,
                                                is_diagonal)

            min_vec = get_smallest_vector_of_atom_pair(atom1, atom2, cell,
                                                       symprec)
            min_distance = np.linalg.norm(np.dot(lattice, min_vec))
            dds_atom2["distance"] = min_distance
            dds_atom1["second_atoms"].append(dds_atom2)
        dds.append(dds_atom1)

    return dds