コード例 #1
0
def write_born_file(initial_structure, phonopy_inputs, dielectric_tensor,
                    born_effective_charge_tensor, file_path):
    """
	Creates the born file that phonopy needs for the non-analytical correction to be applied.
	"""

    phonon = get_initialized_phononopy_instance(initial_structure,
                                                phonopy_inputs)

    symm = Symmetry(cell=phonon.get_primitive(),
                    symprec=phonopy_inputs['symprec'])

    independent_atom_indices_list = symm.get_independent_atoms()

    born_file = File()

    born_file += "14.400"

    flat_dielectric_list = misc.flatten_multi_dimensional_list(
        dielectric_tensor)

    born_file += " ".join(str(component) for component in flat_dielectric_list)

    print "Independent atom indices:", independent_atom_indices_list

    for atomic_bec_index in independent_atom_indices_list:
        atomic_bec = born_effective_charge_tensor[atomic_bec_index]

        flat_atomic_bec = misc.flatten_multi_dimensional_list(atomic_bec)

        born_file += " ".join(str(component) for component in flat_atomic_bec)

    born_file.write_to_path(file_path)
コード例 #2
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
コード例 #3
0
ファイル: wien2k.py プロジェクト: xdlzuups/phonopy
def write_supercells_with_displacements(supercell,
                                        cells_with_displacements,
                                        ids,
                                        npts,
                                        r0s,
                                        rmts,
                                        num_unitcells_in_supercell,
                                        pre_filename="wien2k",
                                        width=3):
    npts_super = []
    r0s_super = []
    rmts_super = []
    for i, j, k in zip(npts, r0s, rmts):
        for l in range(num_unitcells_in_supercell):
            npts_super.append(i)
            r0s_super.append(j)
            rmts_super.append(k)

    _pre_filename = pre_filename.split('/')[-1] + "S"
    write_wein2k(_pre_filename, supercell, npts_super, r0s_super, rmts_super)

    for i, cell in zip(ids, cells_with_displacements):
        symmetry = Symmetry(cell)
        filename = "{pre_filename}-{0:0{width}}.in".format(
            i, pre_filename=_pre_filename, width=width)
        print("Number of non-equivalent atoms in %s: %d" %
              (filename, len(symmetry.get_independent_atoms())))
        write_wein2k(filename, cell, npts_super, r0s_super, rmts_super)
コード例 #4
0
ファイル: vasp.py プロジェクト: georgeyumnam/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,
    symprec=1e-5,
):
    ucell = read_vasp(poscar_filename)
    outcar = open(outcar_filename)

    borns, epsilon = _read_born_and_epsilon(outcar)
    num_atom = len(borns)
    assert num_atom == ucell.get_number_of_atoms()

    if symmetrize_tensors:
        lattice = ucell.get_cell().T
        positions = ucell.get_scaled_positions()
        u_sym = Symmetry(ucell, is_symmetry=is_symmetry, symprec=symprec)
        point_sym = [similarity_transformation(lattice, r) for r in u_sym.get_pointgroup_operations()]
        epsilon = _symmetrize_tensor(epsilon, point_sym)
        borns = _symmetrize_borns(borns, u_sym, lattice, positions, symprec)

    inv_smat = np.linalg.inv(supercell_matrix)
    scell = get_supercell(ucell, supercell_matrix, symprec=symprec)
    pcell = get_primitive(scell, np.dot(inv_smat, primitive_axis), symprec=symprec)
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype="intc")
    p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec)
    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
ファイル: vasp.py プロジェクト: xj361685640/phonopy
def _extract_independent_borns(borns,
                               ucell,
                               primitive_matrix=None,
                               supercell_matrix=None,
                               is_symmetry=True,
                               symprec=1e-5):
    if primitive_matrix is None:
        pmat = np.eye(3)
    else:
        pmat = primitive_matrix
    if supercell_matrix is None:
        smat = np.eye(3, dtype='intc')
    else:
        smat = supercell_matrix

    inv_smat = np.linalg.inv(smat)
    scell = get_supercell(ucell, smat, symprec=symprec)
    pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec)
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc')
    p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec)
    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, s_indep_atoms
コード例 #6
0
ファイル: wien2k.py プロジェクト: Johnson-Wang/phonopy
def write_supercells_with_displacements( supercell,
                                         cells_with_displacements,
                                         npts, r0s, rmts,
                                         supercell_matrix,
                                         filename="wien2k-" ):
    v = supercell_matrix
    det = v[0,0] * v[1,1] * v[2,2] \
        + v[0,1] * v[1,2] * v[2,0] \
        + v[0,2] * v[1,0] * v[2,1] \
        - v[0,0] * v[1,2] * v[2,1] \
        - v[0,1] * v[1,0] * v[2,2] \
        - v[0,2] * v[1,1] * v[2,0]
        
    npts_super = []
    r0s_super = []
    rmts_super = []
    for i, j, k in zip(npts, r0s, rmts):
        for l in range(abs(det)):
            npts_super.append(i)
            r0s_super.append(j)
            rmts_super.append(k)

    w = open(filename.split('/')[-1]+"S", 'w')
    w.write( get_wien2k_struct(supercell, npts_super, r0s_super, rmts_super) )
    w.close()
    for i, cell in enumerate( cells_with_displacements ):
        symmetry = Symmetry( cell )
        print "Number of non-equivalent atoms in %sS-%03d: %d" % (
            filename, i+1, len( symmetry.get_independent_atoms() ) )
        w = open(filename.split('/')[-1]+"S-%03d" % (i+1), 'w')
        w.write( get_wien2k_struct(cell, npts_super, r0s_super, rmts_super) )
        w.close()
コード例 #7
0
def write_supercells_with_displacements(supercell,
                                        cells_with_displacements,
                                        npts,
                                        r0s,
                                        rmts,
                                        supercell_matrix,
                                        filename="wien2k-"):
    v = supercell_matrix
    det = v[0,0] * v[1,1] * v[2,2] \
        + v[0,1] * v[1,2] * v[2,0] \
        + v[0,2] * v[1,0] * v[2,1] \
        - v[0,0] * v[1,2] * v[2,1] \
        - v[0,1] * v[1,0] * v[2,2] \
        - v[0,2] * v[1,1] * v[2,0]

    npts_super = []
    r0s_super = []
    rmts_super = []
    for i, j, k in zip(npts, r0s, rmts):
        for l in range(abs(det)):
            npts_super.append(i)
            r0s_super.append(j)
            rmts_super.append(k)

    w = open(filename.split('/')[-1] + "S", 'w')
    w.write(get_wien2k_struct(supercell, npts_super, r0s_super, rmts_super))
    w.close()
    for i, cell in enumerate(cells_with_displacements):
        symmetry = Symmetry(cell)
        print "Number of non-equivalent atoms in %sS-%03d: %d" % (
            filename, i + 1, len(symmetry.get_independent_atoms()))
        w = open(filename.split('/')[-1] + "S-%03d" % (i + 1), 'w')
        w.write(get_wien2k_struct(cell, npts_super, r0s_super, rmts_super))
        w.close()
コード例 #8
0
def write_supercells_with_displacements(supercell,
                                        cells_with_displacements,
                                        npts,
                                        r0s,
                                        rmts,
                                        num_unitcells_in_supercell,
                                        filename="wien2k-"):
    npts_super = []
    r0s_super = []
    rmts_super = []
    for i, j, k in zip(npts, r0s, rmts):
        for l in range(num_unitcells_in_supercell):
            npts_super.append(i)
            r0s_super.append(j)
            rmts_super.append(k)

    w = open(filename.split('/')[-1] + "S", 'w')
    w.write(_get_wien2k_struct(supercell, npts_super, r0s_super, rmts_super))
    w.close()
    for i, cell in enumerate(cells_with_displacements):
        symmetry = Symmetry(cell)
        supercell_filename = filename.split('/')[-1] + "S-%03d" % (i + 1)
        print("Number of non-equivalent atoms in %s: %d" %
              (supercell_filename, len(symmetry.get_independent_atoms())))
        w = open(supercell_filename, 'w')
        w.write(_get_wien2k_struct(cell, npts_super, r0s_super, rmts_super))
        w.close()
コード例 #9
0
ファイル: wien2k.py プロジェクト: atztogo/phonopy
def _distribute_forces(supercell, disp, forces, filename, symprec):
    natom = supercell.get_number_of_atoms()
    lattice = supercell.get_cell()
    symbols = supercell.get_chemical_symbols()
    positions = supercell.get_positions()
    positions[disp[0]] += disp[1]
    cell = Atoms(cell=lattice, positions=positions, symbols=symbols, pbc=True)
    symmetry = Symmetry(cell, symprec)
    independent_atoms = symmetry.get_independent_atoms()

    # Rotation matrices in Cartesian
    rotations = []
    for r in symmetry.get_symmetry_operations()["rotations"]:
        rotations.append(similarity_transformation(lattice.T, r))

    map_operations = symmetry.get_map_operations()
    map_atoms = symmetry.get_map_atoms()

    atoms_in_dot_scf = _get_independent_atoms_in_dot_scf(filename)

    if len(forces) != len(atoms_in_dot_scf):
        print("%s does not contain necessary information." % filename)
        print('Plese check if there are "FGL" lines with')
        print('"total forces" are required.')
        return False

    if len(atoms_in_dot_scf) == natom:
        print("It is assumed that there is no symmetrically-equivalent " "atoms in ")
        print("'%s' at wien2k calculation." % filename)
        force_set = forces
    elif len(forces) != len(independent_atoms):
        print("Non-equivalent atoms of %s could not be recognized by phonopy." % filename)
        return False
    else:
        # 1. Transform wien2k forces to those on independent atoms
        indep_atoms_to_wien2k = []
        forces_remap = []
        for i, pos_wien2k in enumerate(atoms_in_dot_scf):
            for j, pos in enumerate(cell.get_scaled_positions()):
                diff = pos_wien2k - pos
                diff -= np.rint(diff)
                if (abs(diff) < symprec).all():
                    forces_remap.append(np.dot(rotations[map_operations[j]], forces[i]))
                    indep_atoms_to_wien2k.append(map_atoms[j])
                    break

        if len(forces_remap) != len(forces):
            print("Atomic position mapping between Wien2k and phonopy failed.")
            print("If you think this is caused by a bug of phonopy")
            print("please report it in the phonopy mainling list.")
            return False

        # 2. Distribute forces from independent to dependent atoms.
        force_set = []
        for i in range(natom):
            j = indep_atoms_to_wien2k.index(map_atoms[i])
            force_set.append(np.dot(rotations[map_operations[i]].T, forces_remap[j]))

    return force_set
コード例 #10
0
ファイル: file_IO.py プロジェクト: Johnson-Wang/phonopy
def get_born_parameters(f, primitive, is_symmetry):
    # Read unit conversion factor, damping factor, ...
    factors = [float(x) for x in f.readline().split()]
    if len(factors) < 1:
        print "BORN file format of line 1 is incorrect"
        return False
    if len(factors) < 2:
        factors = factors[0]

    # Read dielectric constant
    line = f.readline().split()
    if not len(line) == 9:
        print "BORN file format of line 2 is incorrect"
        return False
    dielectric = np.reshape([float(x) for x in line], (3, 3))

    # Read Born effective charge
    symmetry = Symmetry(primitive, is_symmetry=is_symmetry)
    independent_atoms = symmetry.get_independent_atoms()
    born = np.zeros((primitive.get_number_of_atoms(), 3, 3), dtype=float)

    for i in independent_atoms:
        line = f.readline().split()
        if len(line) == 0:
            print "Number of lines for Born effect charge is not enough."
            return False
        if not len(line) == 9:
            print "BORN file format of line %d is incorrect" % (i + 3)
            return False
        born[i] = np.reshape([float(x) for x in line], (3, 3))

    # Expand Born effective charges to all atoms in the primitive cell
    rotations = symmetry.get_symmetry_operations()['rotations']
    map_operations = symmetry.get_map_operations()
    map_atoms = symmetry.get_map_atoms()

    for i in range(primitive.get_number_of_atoms()):
        # R_cart = L R L^-1
        rot_cartesian = similarity_transformation(
            primitive.get_cell().transpose(), rotations[map_operations[i]])
        # R_cart^T B R_cart^-T (inverse rotation is required to transform)
        born[i] = similarity_transformation(rot_cartesian.transpose(),
                                            born[map_atoms[i]])

    non_anal = {'born': born,
                'factor': factors,
                'dielectric': dielectric }

    return non_anal
コード例 #11
0
ファイル: file_IO.py プロジェクト: jasonlarkin/ntpl
def parse_BORN( primitive,  filename = "BORN" ):
    file = open( filename, 'r' )

    # Read unit conversion factor, damping factor, ...
    factors = [ float( x ) for x in file.readline().split() ]
    if len( factors ) < 1:
        print "BORN file format of line 1 is incorrect"
        return None
    if len( factors ) < 2:
        factors.append( Damping_Factor )

    # Read dielectric constant
    line = file.readline().split()
    if 9 < len( line ) or len( line ) < 9:
        print "BORN file format of line 2 is incorrect"
        return None
    dielectric = np.reshape( [ float( x ) for x in line ], ( 3, 3 ) )

    # Read Born effective charge
    symmetry = Symmetry( primitive )
    independent_atoms = symmetry.get_independent_atoms()
    born = np.zeros( ( primitive.get_number_of_atoms(), 3, 3 ), dtype=float )

    for i in independent_atoms:
        line = file.readline().split()
        if 9 < len( line ) or len( line ) < 9:
            print "BORN file format of line %d is incorrect" % ( i + 3 )
            return None
        born[ i ] = np.reshape( [ float( x ) for x in line ], ( 3, 3 ) )

    # Expand Born effective charges to all atoms in the primitive cell
    rotations = symmetry.get_symmetry_operations()['rotations']
    map_operations = symmetry.get_map_operations()
    map_atoms = symmetry.get_map_atoms()

    for i in range( primitive.get_number_of_atoms() ):
        # R_cart = L R L^-1
        rot_cartesian = similarity_transformation(
            primitive.get_cell().transpose(), rotations[ map_operations[i] ] )
        # R_cart^T B R_cart^-T ( inverse rotation is required to transform )
        born[i] = similarity_transformation( rot_cartesian.transpose(),
                                             born[ map_atoms[ i ] ] )

    non_anal = {'born': born,
                'factor': factors,
                'dielectric': dielectric }

    return non_anal
コード例 #12
0
def get_born_parameters(f, primitive, is_symmetry):
    # Read unit conversion factor, damping factor, ...
    factors = [float(x) for x in f.readline().split()]
    if len(factors) < 1:
        print "BORN file format of line 1 is incorrect"
        return False
    if len(factors) < 2:
        factors = factors[0]

    # Read dielectric constant
    line = f.readline().split()
    if not len(line) == 9:
        print "BORN file format of line 2 is incorrect"
        return False
    dielectric = np.reshape([float(x) for x in line], (3, 3))

    # Read Born effective charge
    symmetry = Symmetry(primitive, is_symmetry=is_symmetry)
    independent_atoms = symmetry.get_independent_atoms()
    born = np.zeros((primitive.get_number_of_atoms(), 3, 3), dtype=float)

    for i in independent_atoms:
        line = f.readline().split()
        if len(line) == 0:
            print "Number of lines for Born effect charge is not enough."
            return False
        if not len(line) == 9:
            print "BORN file format of line %d is incorrect" % (i + 3)
            return False
        born[i] = np.reshape([float(x) for x in line], (3, 3))

    # Expand Born effective charges to all atoms in the primitive cell
    rotations = symmetry.get_symmetry_operations()['rotations']
    map_operations = symmetry.get_map_operations()
    map_atoms = symmetry.get_map_atoms()

    for i in range(primitive.get_number_of_atoms()):
        # R_cart = L R L^-1
        rot_cartesian = similarity_transformation(
            primitive.get_cell().transpose(), rotations[map_operations[i]])
        # R_cart^T B R_cart^-T (inverse rotation is required to transform)
        born[i] = similarity_transformation(rot_cartesian.transpose(),
                                            born[map_atoms[i]])

    non_anal = {'born': born, 'factor': factors, 'dielectric': dielectric}

    return non_anal
コード例 #13
0
def get_BORN_txt(structure, parameters, nac_data, symprec=1.e-5):

    from phonopy.structure.cells import get_primitive, get_supercell
    from phonopy.structure.symmetry import Symmetry
    from phonopy.interface import get_default_physical_units
    from phonopy.structure.atoms import Atoms as PhonopyAtoms

    born_charges = nac_data.get_array('born_charges')
    epsilon = nac_data.get_array('epsilon')

    print ('inside born parameters')
    pmat = parameters['primitive']
    smat = parameters['supercell']

    ucell = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                         positions=[site.position for site in structure.sites],
                         cell=structure.cell)

    num_atom = len(born_charges)
    assert num_atom == ucell.get_number_of_atoms(), \
        "num_atom %d != len(borns) %d" % (ucell.get_number_of_atoms(),
                                          len(born_charges))

    inv_smat = np.linalg.inv(smat)
    scell = get_supercell(ucell, smat, symprec=symprec)
    pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec)
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc')
    p_sym = Symmetry(pcell, is_symmetry=True, symprec=symprec)
    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 = born_charges[u_indep_atoms].copy()

    factor = get_default_physical_units('vasp')['nac_factor']  # born charges in VASP units

    born_txt = ('{}\n'.format(factor))
    for num in epsilon.flatten():
        born_txt += ('{0:4.8f}'.format(num))
    born_txt += ('\n')

    for atom in reduced_borns:
        for num in atom:
            born_txt += ('{0:4.8f}'.format(num))
        born_txt += ('\n')
    born_txt += ('{}\n'.format(factor))

    return born_txt
コード例 #14
0
def get_born_OUTCAR(poscar_filename="POSCAR",
                    outcar_filename="OUTCAR",
                    primitive_matrix=None,
                    supercell_matrix=None,
                    is_symmetry=True,
                    symmetrize_tensors=False,
                    symprec=1e-5):
    if primitive_matrix is None:
        pmat = np.eye(3)
    else:
        pmat = primitive_matrix
    if supercell_matrix is None:
        smat = np.eye(3, dtype='intc')
    else:
        smat = supercell_matrix
    ucell = read_vasp(poscar_filename)
    outcar = open(outcar_filename)

    borns, epsilon = _read_born_and_epsilon(outcar)
    num_atom = len(borns)
    assert num_atom == ucell.get_number_of_atoms()

    if symmetrize_tensors:
        lattice = ucell.get_cell().T
        positions = ucell.get_scaled_positions()
        u_sym = Symmetry(ucell, is_symmetry=is_symmetry, symprec=symprec)
        point_sym = [
            similarity_transformation(lattice, r)
            for r in u_sym.get_pointgroup_operations()
        ]
        epsilon = _symmetrize_tensor(epsilon, point_sym)
        borns = _symmetrize_borns(borns, u_sym, lattice, positions, symprec)

    inv_smat = np.linalg.inv(smat)
    scell = get_supercell(ucell, smat, symprec=symprec)
    pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec)
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc')
    p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec)
    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, s_indep_atoms
コード例 #15
0
def get_born_parameters(phonon, born_charges, epsilon, symprec=1e-5):
    from phonopy.structure.cells import get_primitive, get_supercell
    from phonopy.structure.symmetry import Symmetry
    from phonopy.interface import get_default_physical_units

    print('inside born parameters')
    pmat = phonon.get_primitive_matrix()
    smat = phonon.get_supercell_matrix()
    ucell = phonon.get_unitcell()

    print pmat
    print smat
    print ucell

    num_atom = len(born_charges)
    assert num_atom == ucell.get_number_of_atoms(), \
        "num_atom %d != len(borns) %d" % (ucell.get_number_of_atoms(),
                                          len(born_charges))

    inv_smat = np.linalg.inv(smat)
    scell = get_supercell(ucell, smat, symprec=symprec)
    pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec)
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc')
    p_sym = Symmetry(pcell, is_symmetry=True, symprec=symprec)
    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 = born_charges[u_indep_atoms].copy()

    factor = get_default_physical_units('vasp')[
        'nac_factor']  # born charges in VASP units

    born_dict = {
        'born': reduced_borns,
        'dielectric': epsilon,
        'factor': factor
    }

    print('final born dict', born_dict)

    return born_dict
コード例 #16
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
コード例 #17
0
def distribute_forces(supercell, disp, forces, filename, symprec):
    natom = supercell.get_number_of_atoms()
    lattice = supercell.get_cell()
    symbols = supercell.get_chemical_symbols()
    positions = supercell.get_positions()
    positions[disp[0]] += disp[1]
    cell = Atoms(cell=lattice, positions=positions, symbols=symbols, pbc=True)
    symmetry = Symmetry(cell, symprec)
    independent_atoms = symmetry.get_independent_atoms()

    # Rotation matrices in Cartesian
    rotations = []
    for r in symmetry.get_symmetry_operations()['rotations']:
        rotations.append(similarity_transformation(lattice.T, r))

    map_operations = symmetry.get_map_operations()
    map_atoms = symmetry.get_map_atoms()

    atoms_in_dot_scf = get_independent_atoms_in_dot_scf(filename)

    if not len(forces) == len(atoms_in_dot_scf):
        print "%s does not contain necessary information." % filename
        print "Plese check if there are \"FGL\" lines with"
        print "\"total forces\" are required."
        return False

    if len(atoms_in_dot_scf) == natom:
        print "It is assumed that there is no symmetrically-equivalent atoms in "
        print "\'%s\' at wien2k calculation." % filename
        print ""
        force_set = forces
    elif not len(forces) == len(independent_atoms):
        print "Non-equivalent atoms of %s could not be recognized by phonopy." % filename
        return False
    else:
        # 1. Transform wien2k forces to those on independent atoms
        indep_atoms_to_wien2k = []
        forces_remap = []
        for i, pos_wien2k in enumerate(atoms_in_dot_scf):
            for j, pos in enumerate(cell.get_scaled_positions()):
                diff = pos_wien2k - pos
                diff -= np.rint(diff)
                if (abs(diff) < 0.00001).all():
                    forces_remap.append(
                        np.dot(forces[i], rotations[map_operations[j]].T))
                    indep_atoms_to_wien2k.append(map_atoms[j])
                    break

        if not len(forces_remap) == len(forces):
            print "Atomic position mapping between Wien2k and phonopy failed."
            print "If you think this is caused by a bug of phonopy"
            print "please report it in the phonopy mainling list."
            return False

        # 2. Distribute forces from independent to dependent atoms.
        force_set = []
        for i in range(natom):
            force_set.append(
                np.dot(forces_remap[indep_atoms_to_wien2k.index(map_atoms[i])],
                       rotations[map_operations[i]]))

    return force_set
コード例 #18
0
    def average_force_constants_spg(self, symprec=1e-5):
        atoms = self._atoms
        fc_orig = self._force_constants

        atoms_symmetry = self._atoms_ideal

        symmetry = Symmetry(atoms_symmetry)

        symbols = atoms.get_chemical_symbols()
        symboltypes = sorted(set(symbols), key=symbols.index)

        rotations_cart = get_rotations_cart(atoms_symmetry)
        mappings = StructureAnalyzer(
            atoms_symmetry).get_mappings_for_symops(prec=symprec)
        mappings_inv = MappingsModifier(mappings).invert_mappings()

        print("mappings: Finished.")
        (nsym, natoms) = mappings.shape
        print("nsym: {}".format(nsym))
        print("natoms: {}".format(natoms))

        fc_mean = np.zeros_like(fc_orig)
        fc_mean_square = np.zeros_like(fc_orig)

        fc_mean_symbols, fc_mean_square_symbols, fc_std_symbols, counters = (
            self.initialize_fc_symbols(fc_orig, symboltypes)
        )

        for (minv, r) in zip(mappings_inv, rotations_cart):
            for i1 in symmetry.get_independent_atoms():
                for i2 in range(natoms):
                    j1 = minv[i1]
                    j2 = minv[i2]
                    s1 = symbols[j1]
                    s2 = symbols[j2]

                    tmp = np.dot(np.dot(r, fc_orig[j1, j2]), r.T)
                    tmp2 = tmp ** 2
                    fc_mean[i1, i2] += tmp
                    fc_mean_square[i1, i2] += tmp2

                    fc_mean_symbols[(s1, s2)][i1, i2] += tmp
                    fc_mean_square_symbols[(s1, s2)][i1, i2] += tmp2

                    counters[(s1, s2)][i1, i2] += 1

        fc_mean        /= float(len(rotations_cart))
        fc_mean_square /= float(len(rotations_cart))

        for i1 in symmetry.get_independent_atoms():
            for i2 in range(natoms):
                for (key, c) in counters.items():
                    if c[i1, i2] != 0:
                        fc_mean_symbols       [key][i1, i2] /= c[i1, i2]
                        fc_mean_square_symbols[key][i1, i2] /= c[i1, i2]
                    else:
                        fc_mean_symbols       [key][i1, i2] = np.nan
                        fc_mean_square_symbols[key][i1, i2] = np.nan

        ########################################
        # STD
        ########################################
        fc_std = get_matrix_std(fc_mean, fc_mean_square)

        for key in counters.keys():
            fc_std_symbols[key] = get_matrix_std(
                fc_mean_symbols[key], fc_mean_square_symbols[key])

        ########################################
        # Distribution
        ########################################
        fc_mean = self.distribute_force_constants_spg(
            fc_mean, symmetry, rotations_cart, mappings)
        fc_std = self.distribute_force_constants_spg(
            fc_std, symmetry, rotations_cart, mappings)

        for key in counters.keys():
            fc_mean_symbols[key] = self.distribute_force_constants_spg(
                fc_mean_symbols[key], symmetry, rotations_cart, mappings)
            fc_std_symbols[key] = self.distribute_force_constants_spg(
                fc_std_symbols[key], symmetry, rotations_cart, mappings)

        # After the distributions, the signs of SDs can be changed.
        # However, the signs of SDs have no meaning.
        # To suppress the meaningless signs, we take the absolute values here.
        # TODO(ikeda): Consider the meaning of SDs for vectors or tensors.
        fc_std = np.abs(fc_std)
        for key in counters.keys():
            fc_std_symbols[key] = np.abs(fc_std_symbols[key])

        self._force_constants_symmetrized = fc_mean
        self._force_constants_sd = fc_std
        self._force_constants_pair = fc_mean_symbols
        self._force_constants_pair_sd = fc_std_symbols
コード例 #19
0
    def average_force_constants_spg(self, symprec=1e-5):
        atoms = self._atoms
        fc_orig = self._force_constants

        atoms_symmetry = self._atoms_ideal

        symmetry = Symmetry(atoms_symmetry)

        symbols = atoms.get_chemical_symbols()
        symboltypes = sorted(set(symbols), key=symbols.index)

        rotations_cart = get_rotations_cart(atoms_symmetry)
        mappings = StructureAnalyzer(atoms_symmetry).get_mappings_for_symops(
            prec=symprec)
        mappings_inv = MappingsModifier(mappings).invert_mappings()

        print("mappings: Finished.")
        (nsym, natoms) = mappings.shape
        print("nsym: {}".format(nsym))
        print("natoms: {}".format(natoms))

        fc_mean = np.zeros_like(fc_orig)
        fc_mean_square = np.zeros_like(fc_orig)

        fc_mean_symbols, fc_mean_square_symbols, fc_std_symbols, counters = (
            self.initialize_fc_symbols(fc_orig, symboltypes))

        for (minv, r) in zip(mappings_inv, rotations_cart):
            for i1 in symmetry.get_independent_atoms():
                for i2 in range(natoms):
                    j1 = minv[i1]
                    j2 = minv[i2]
                    s1 = symbols[j1]
                    s2 = symbols[j2]

                    tmp = np.dot(np.dot(r, fc_orig[j1, j2]), r.T)
                    tmp2 = tmp**2
                    fc_mean[i1, i2] += tmp
                    fc_mean_square[i1, i2] += tmp2

                    fc_mean_symbols[(s1, s2)][i1, i2] += tmp
                    fc_mean_square_symbols[(s1, s2)][i1, i2] += tmp2

                    counters[(s1, s2)][i1, i2] += 1

        fc_mean /= float(len(rotations_cart))
        fc_mean_square /= float(len(rotations_cart))

        for i1 in symmetry.get_independent_atoms():
            for i2 in range(natoms):
                for (key, c) in counters.items():
                    if c[i1, i2] != 0:
                        fc_mean_symbols[key][i1, i2] /= c[i1, i2]
                        fc_mean_square_symbols[key][i1, i2] /= c[i1, i2]
                    else:
                        fc_mean_symbols[key][i1, i2] = np.nan
                        fc_mean_square_symbols[key][i1, i2] = np.nan

        ########################################
        # STD
        ########################################
        fc_std = get_matrix_std(fc_mean, fc_mean_square)

        for key in counters.keys():
            fc_std_symbols[key] = get_matrix_std(fc_mean_symbols[key],
                                                 fc_mean_square_symbols[key])

        ########################################
        # Distribution
        ########################################
        fc_mean = self.distribute_force_constants_spg(fc_mean, symmetry,
                                                      rotations_cart, mappings)
        fc_std = self.distribute_force_constants_spg(fc_std, symmetry,
                                                     rotations_cart, mappings)

        for key in counters.keys():
            fc_mean_symbols[key] = self.distribute_force_constants_spg(
                fc_mean_symbols[key], symmetry, rotations_cart, mappings)
            fc_std_symbols[key] = self.distribute_force_constants_spg(
                fc_std_symbols[key], symmetry, rotations_cart, mappings)

        # After the distributions, the signs of SDs can be changed.
        # However, the signs of SDs have no meaning.
        # To suppress the meaningless signs, we take the absolute values here.
        # TODO(ikeda): Consider the meaning of SDs for vectors or tensors.
        fc_std = np.abs(fc_std)
        for key in counters.keys():
            fc_std_symbols[key] = np.abs(fc_std_symbols[key])

        self._force_constants_symmetrized = fc_mean
        self._force_constants_sd = fc_std
        self._force_constants_pair = fc_mean_symbols
        self._force_constants_pair_sd = fc_std_symbols
コード例 #20
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
コード例 #21
0
def get_born_OUTCAR(poscar_filename="POSCAR",
                    outcar_filename=None,
                    primitive_matrix=None,
                    supercell_matrix=None,
                    is_symmetry=True,
                    symmetrize_tensors=False,
                    read_vasprunxml=False,
                    symprec=1e-5):
    if outcar_filename is None:
        if read_vasprunxml:
            filename = "vasprun.xml"
        else:
            filename = "OUTCAR"
    else:
        filename = outcar_filename
    if primitive_matrix is None:
        pmat = np.eye(3)
    else:
        pmat = primitive_matrix
    if supercell_matrix is None:
        smat = np.eye(3, dtype='intc')
    else:
        smat = supercell_matrix
    ucell = read_vasp(poscar_filename)

    if read_vasprunxml:
        import io
        borns = []
        epsilon = []
        with io.open(outcar_filename, "rb") as f:
            vasprun = VasprunxmlExpat(f)
            if vasprun.parse():
                epsilon = vasprun.get_epsilon()
                borns = vasprun.get_born()
    else:
        borns, epsilon = _read_born_and_epsilon(filename)

    num_atom = len(borns)
    assert num_atom == ucell.get_number_of_atoms(), \
        "num_atom %d != len(borns) %d" % (ucell.get_number_of_atoms(),
                                          len(borns))

    if symmetrize_tensors:
        lattice = ucell.get_cell()
        positions = ucell.get_scaled_positions()
        u_sym = Symmetry(ucell, is_symmetry=is_symmetry, symprec=symprec)
        rotations = u_sym.get_symmetry_operations()['rotations']
        translations = u_sym.get_symmetry_operations()['translations']
        ptg_ops = get_pointgroup_operations(rotations)
        epsilon = symmetrize_2nd_rank_tensor(epsilon,
                                             ptg_ops,
                                             lattice)
        borns = symmetrize_borns(borns,
                                 rotations,
                                 translations,
                                 lattice,
                                 positions,
                                 symprec)

    inv_smat = np.linalg.inv(smat)
    scell = get_supercell(ucell, smat, symprec=symprec)
    pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec)
    p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc')
    p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec)
    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, s_indep_atoms