示例#1
0
 def _search_primitive_symmetry(self):
     self._primitive_symmetry = Symmetry(self._primitive, self._symprec,
                                         self._is_symmetry)
     if (len(self._symmetry.get_pointgroup_operations()) != len(
             self._primitive_symmetry.get_pointgroup_operations())):
         print("Warning: point group symmetries of supercell and primitive"
               "cell are different.")
示例#2
0
def check_symmetry(input_cell,
                   primitive_axis=np.eye(3, dtype=float),
                   symprec=1e-5,
                   phonopy_version=None):

    cell = Primitive(input_cell, primitive_axis, symprec)

    symmetry = Symmetry(cell, symprec)
    print get_symmetry_yaml(cell, symmetry, phonopy_version),

    if input_cell.get_magnetic_moments() == None:
        primitive = find_primitive(cell, symprec)
        if not primitive == None:
            print "# Primitive cell was found. It is written into PPOSCAR."
            write_vasp('PPOSCAR', primitive)

            # Overwrite symmetry and cell
            symmetry = Symmetry(primitive, symprec)
            cell = primitive

        bravais_lattice, bravais_pos, bravais_numbers = \
            spg.refine_cell(cell, symprec)
        bravais = Atoms(numbers=bravais_numbers,
                        scaled_positions=bravais_pos,
                        cell=bravais_lattice,
                        pbc=True)
        print "# Bravais lattice is written into BPOSCAR."
        write_vasp('BPOSCAR', bravais)
示例#3
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()
示例#4
0
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
def gencastep(fn,modenum,basis,natom,typatsym,symprec,atpos):
    from phonopy import Phonopy
    import phonopy.structure.spglib as spg
    from phonopy.structure.atoms import PhonopyAtoms as Atoms
    from phonopy.structure.symmetry import Symmetry, find_primitive, get_pointgroup

    fh=open(fn,'w')
    unitcell = Atoms(symbols=typatsym, cell=basis, positions=atpos)
    pbasis=np.eye(3)
    for i in range(len(basis)):
        pbasis[i]=basis[i]/np.linalg.norm(basis[i])
    symmetry = Symmetry(unitcell, symprec)
    rotations = symmetry.get_symmetry_operations()['rotations']
    translations = symmetry.get_symmetry_operations()['translations']
    print('Space group International symbol: %s' % symmetry.get_international_table())

    fh.write('%BLOCK LATTICE_CART\n')
    for bl in basis:
        fh.write('%s\n' % ''.join(' %12.8f' % b for b in bl))
    fh.write('%ENDBLOCK LATTICE_CART\n\n')
    fh.write('%BLOCK POSITIONS_ABS\n')
    for i in range(len(typatsym)):
        fh.write("  %3s   " % typatsym[i])
        fh.write('%s\n' % ''.join(' %12.8f' % p for p in atpos[i].tolist()))
    fh.write('%ENDBLOCK POSITIONS_ABS\n\n')

    fh.write('SYMMETRY_TOL : %f ang\n' % symprec)
    fh.write('SYMMETRY_GENERATE \n')
    fh.write('#KPOINT_MP_GRID : 4 4 4\n#KPOINT_MP_OFFSET : 0.5 0.5 0.5\n')
def gencastep(fn, modenum, basis, natom, typatsym, symprec, atpos):
    from phonopy import Phonopy
    import phonopy.structure.spglib as spg
    from phonopy.structure.atoms import PhonopyAtoms as Atoms
    from phonopy.structure.symmetry import Symmetry, find_primitive, get_pointgroup

    fh = open(fn, 'w')
    unitcell = Atoms(symbols=typatsym, cell=basis, positions=atpos)
    pbasis = np.eye(3)
    for i in range(len(basis)):
        pbasis[i] = basis[i] / np.linalg.norm(basis[i])
    symmetry = Symmetry(unitcell, symprec)
    rotations = symmetry.get_symmetry_operations()['rotations']
    translations = symmetry.get_symmetry_operations()['translations']
    print('Space group International symbol: %s' %
          symmetry.get_international_table())

    fh.write('%BLOCK LATTICE_CART\n')
    for bl in basis:
        fh.write('%s\n' % ''.join(' %12.8f' % b for b in bl))
    fh.write('%ENDBLOCK LATTICE_CART\n\n')
    fh.write('%BLOCK POSITIONS_ABS\n')
    for i in range(len(typatsym)):
        fh.write("  %3s   " % typatsym[i])
        fh.write('%s\n' % ''.join(' %12.8f' % p for p in atpos[i].tolist()))
    fh.write('%ENDBLOCK POSITIONS_ABS\n\n')

    fh.write('SYMMETRY_TOL : %f ang\n' % symprec)
    fh.write('SYMMETRY_GENERATE \n')
    fh.write('#KPOINT_MP_GRID : 4 4 4\n#KPOINT_MP_OFFSET : 0.5 0.5 0.5\n')
示例#7
0
    def __init__(self,
                 fc4,
                 supercell,
                 primitive,
                 mesh,
                 temperatures=None,
                 band_indices=None,
                 frequency_factor_to_THz=VaspToTHz,
                 is_nosym=False,
                 symprec=1e-3,
                 cutoff_frequency=1e-4,
                 log_level=False,
                 lapack_zheev_uplo='L'):
        self._fc4 = fc4
        self._supercell = supercell
        self._primitive = primitive
        self._masses = np.double(self._primitive.get_masses())
        self._mesh = np.intc(mesh)
        if temperatures is None:
            self._temperatures = np.double([0])
        else:
            self._temperatures = np.double(temperatures)
        num_band = primitive.get_number_of_atoms() * 3
        if band_indices is None:
            self._band_indices = np.arange(num_band, dtype='intc')
        else:
            self._band_indices = np.intc(band_indices)
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._is_nosym = is_nosym
        self._symprec = symprec
        self._cutoff_frequency = cutoff_frequency
        self._log_level = log_level
        self._lapack_zheev_uplo = lapack_zheev_uplo

        symmetry = Symmetry(primitive, symprec=symprec)
        self._point_group_operations = symmetry.get_pointgroup_operations()

        self._grid_address = None
        self._bz_map = None
        self._set_grid_address()
        
        self._grid_point = None
        self._quartets_at_q = None
        self._weights_at_q = None

        self._phonon_done = None
        self._frequencies = None
        self._eigenvectors = None
        self._dm = None
        self._nac_q_direction = None

        self._frequency_shifts = None
        
        # Unit to THz of Delta
        self._unit_conversion = (EV / Angstrom ** 4 / AMU ** 2
                                 / (2 * np.pi * THz) ** 2
                                 * Hbar * EV / (2 * np.pi * THz) / 8
                                 / np.prod(self._mesh))

        self._allocate_phonon()
示例#8
0
文件: crystal.py 项目: gcgs1/phonopy
def read_crystal(filename):
    f_crystal = open(filename)
    crystal_in = CrystalIn(f_crystal.readlines())
    f_crystal.close()
    tags = crystal_in.get_tags()
     
     
    cell = Atoms(cell=tags['lattice_vectors'], 
                 symbols=tags['atomic_species'],
                 scaled_positions=tags['coordinates'])
    
    magmoms = tags['magnetic_moments']
    if magmoms is not None:
        # Print out symmetry information for magnetic cases
        # Original code from structure/symmetry.py
        symmetry = Symmetry(cell, symprec=1e-5)
        print("CRYSTAL-interface: Magnetic structure, number of operations without spin: %d" %
              len(symmetry.get_symmetry_operations()['rotations']))
        print("CRYSTAL-interface: Spacegroup without spin: %s" % symmetry.get_international_table())

        cell.set_magnetic_moments(magmoms)
        symmetry = Symmetry(cell, symprec=1e-5)
        print("CRYSTAL-interface: Magnetic structure, number of operations with spin: %d" %
              len(symmetry.get_symmetry_operations()['rotations']))
        print("")
    
    return cell, tags['conv_numbers']
示例#9
0
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)
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)
示例#11
0
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
示例#12
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()
示例#13
0
def check_symmetry(input_cell,
                   primitive_axis=None,
                   symprec=1e-5,
                   distance_to_A=1.0,
                   phonopy_version=None):
    if primitive_axis is None:
        cell = get_primitive(input_cell, np.eye(3), symprec=symprec)
    else:
        cell = get_primitive(input_cell, primitive_axis, symprec=symprec)
    lattice = cell.get_cell() * distance_to_A
    cell.set_cell(lattice)

    symmetry = Symmetry(cell, symprec)
    print(_get_symmetry_yaml(cell, symmetry, phonopy_version))

    if input_cell.get_magnetic_moments() is None:
        primitive = find_primitive(cell, symprec)
        if primitive is not None:
            print("# Primitive cell was found. It is written into PPOSCAR.")
            write_vasp('PPOSCAR', primitive)

            # Overwrite symmetry and cell
            symmetry = Symmetry(primitive, symprec)
            cell = primitive

        (bravais_lattice, bravais_pos,
         bravais_numbers) = spg.refine_cell(cell, symprec)
        bravais = Atoms(numbers=bravais_numbers,
                        scaled_positions=bravais_pos,
                        cell=bravais_lattice,
                        pbc=True)
        print("# Bravais lattice is written into BPOSCAR.")
        write_vasp('BPOSCAR', bravais)
示例#14
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
示例#15
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()
示例#16
0
    def __init__(self,
                 fc4,
                 supercell,
                 primitive,
                 mesh,
                 temperatures=None,
                 band_indices=None,
                 frequency_factor_to_THz=VaspToTHz,
                 is_nosym=False,
                 symprec=1e-3,
                 cutoff_frequency=1e-4,
                 log_level=False,
                 lapack_zheev_uplo='L'):
        self._fc4 = fc4
        self._supercell = supercell
        self._primitive = primitive
        self._masses = np.double(self._primitive.get_masses())
        self._mesh = np.intc(mesh)
        if temperatures is None:
            self._temperatures = np.double([0])
        else:
            self._temperatures = np.double(temperatures)
        num_band = primitive.get_number_of_atoms() * 3
        if band_indices is None:
            self._band_indices = np.arange(num_band, dtype='intc')
        else:
            self._band_indices = np.intc(band_indices)
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._is_nosym = is_nosym
        self._symprec = symprec
        self._cutoff_frequency = cutoff_frequency
        self._log_level = log_level
        self._lapack_zheev_uplo = lapack_zheev_uplo

        symmetry = Symmetry(primitive, symprec=symprec)
        self._point_group_operations = symmetry.get_pointgroup_operations()

        self._grid_address = None
        self._bz_map = None
        self._set_grid_address()

        self._grid_point = None
        self._quartets_at_q = None
        self._weights_at_q = None

        self._phonon_done = None
        self._frequencies = None
        self._eigenvectors = None
        self._dm = None
        self._nac_q_direction = None

        self._frequency_shifts = None

        # Unit to THz of Delta
        self._unit_conversion = (EV / Angstrom**4 / AMU**2 /
                                 (2 * np.pi * THz)**2 * Hbar * EV /
                                 (2 * np.pi * THz) / 8 / np.prod(self._mesh))

        self._allocate_phonon()
示例#17
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
示例#18
0
    def __init__(self,
                 mesh,
                 primitive,
                 supercell,
                 fc2,
                 nac_params=None,
                 nac_q_direction=None,
                 sigma=None,
                 cutoff_frequency=None,
                 frequency_step=None,
                 num_frequency_points=None,
                 temperatures=None,
                 frequency_factor_to_THz=VaspToTHz,
                 frequency_scale_factor=1.0,
                 is_mesh_symmetry=True,
                 symprec=1e-5,
                 filename=None,
                 log_level=False,
                 lapack_zheev_uplo='L'):

        self._grid_point = None
        self._mesh = np.array(mesh, dtype='intc')
        self._primitive = primitive
        self._supercell = supercell
        self._fc2 = fc2
        self._nac_params = nac_params
        self._nac_q_direction = None
        self.set_nac_q_direction(nac_q_direction)
        self._sigma = None
        self.set_sigma(sigma)

        if cutoff_frequency is None:
            self._cutoff_frequency = 0
        else:
            self._cutoff_frequency = cutoff_frequency
        self._frequency_step = frequency_step
        self._num_frequency_points = num_frequency_points
        self._temperatures = temperatures
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._frequency_scale_factor = frequency_scale_factor
        self._is_mesh_symmetry = is_mesh_symmetry
        self._symprec = symprec
        self._filename = filename
        self._log_level = log_level
        self._lapack_zheev_uplo = lapack_zheev_uplo

        self._num_band = self._primitive.get_number_of_atoms() * 3
        self._reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
        self._init_dynamical_matrix()
        self._symmetry = Symmetry(primitive, symprec)

        self._tetrahedron_method = None
        self._phonon_done = None
        self._frequencies = None
        self._eigenvectors = None

        self._joint_dos = None
        self._frequency_points = None
示例#19
0
    def _search_primitive_symmetry_ideal(self):
        self._primitive_symmetry = Symmetry(self._primitive_ideal,
                                            self._symprec,
                                            self._is_symmetry)

        n0 = len(self._symmetry.get_pointgroup_operations())
        n1 = len(self._primitive_symmetry.get_pointgroup_operations())
        if n0 != n1:
            raise Warning("Point group symmetries of supercell and primitive"
                          "cell are different.")
示例#20
0
def get_number_of_triplets(primitive, mesh, grid_point, symprec=1e-5):
    mesh = np.array(mesh, dtype='intc')
    symmetry = Symmetry(primitive, symprec)
    point_group = symmetry.get_pointgroup_operations()
    primitive_lattice = np.linalg.inv(primitive.get_cell())
    triplets_at_q, _, _, _, _, _ = get_triplets_at_q(grid_point, mesh,
                                                     point_group,
                                                     primitive_lattice)

    return len(triplets_at_q)
示例#21
0
    def test_magmom(self):
        symprec = 1e-5
        cell = get_unitcell_from_phonopy_yaml(os.path.join(data_dir,"Cr.yaml"))
        symmetry_nonspin = Symmetry(cell, symprec=symprec)
        atom_map_nonspin = symmetry_nonspin.get_map_atoms()
        len_sym_nonspin = len(
            symmetry_nonspin.get_symmetry_operations()['rotations'])
        
        spin = [1, -1]
        cell_withspin = cell.copy()
        cell_withspin.set_magnetic_moments(spin)
        symmetry_withspin = Symmetry(cell_withspin, symprec=symprec)
        atom_map_withspin = symmetry_withspin.get_map_atoms()
        len_sym_withspin = len(
            symmetry_withspin.get_symmetry_operations()['rotations'])

        broken_spin = [1, -2]
        cell_brokenspin = cell.copy()
        cell_brokenspin = cell.copy()
        cell_brokenspin.set_magnetic_moments(broken_spin)
        symmetry_brokenspin = Symmetry(cell_brokenspin, symprec=symprec)
        atom_map_brokenspin = symmetry_brokenspin.get_map_atoms()
        len_sym_brokenspin = len(
            symmetry_brokenspin.get_symmetry_operations()['rotations'])

        self.assertTrue((atom_map_nonspin == atom_map_withspin).all())
        self.assertFalse((atom_map_nonspin == atom_map_brokenspin).all())
        self.assertTrue(len_sym_nonspin == len_sym_withspin)
        self.assertFalse(len_sym_nonspin == len_sym_brokenspin)
示例#22
0
def test_magmom(convcell_cr: PhonopyAtoms):
    """Test symmetry search with hmagnetic moments."""
    symprec = 1e-5
    symmetry_nonspin = Symmetry(convcell_cr, symprec=symprec)
    atom_map_nonspin = symmetry_nonspin.get_map_atoms()
    len_sym_nonspin = len(symmetry_nonspin.symmetry_operations["rotations"])

    spin = [1, -1]
    cell_withspin = convcell_cr.copy()
    cell_withspin.magnetic_moments = spin
    symmetry_withspin = Symmetry(cell_withspin, symprec=symprec)
    atom_map_withspin = symmetry_withspin.get_map_atoms()
    len_sym_withspin = len(symmetry_withspin.symmetry_operations["rotations"])

    broken_spin = [1, -2]
    cell_brokenspin = convcell_cr.copy()
    cell_brokenspin = convcell_cr.copy()
    cell_brokenspin.magnetic_moments = broken_spin
    symmetry_brokenspin = Symmetry(cell_brokenspin, symprec=symprec)
    atom_map_brokenspin = symmetry_brokenspin.get_map_atoms()
    len_sym_brokenspin = len(
        symmetry_brokenspin.symmetry_operations["rotations"])

    assert (atom_map_nonspin == atom_map_withspin).all()
    assert (atom_map_nonspin != atom_map_brokenspin).any()
    assert len_sym_nonspin == len_sym_withspin
    assert len_sym_nonspin != len_sym_brokenspin
示例#23
0
def get_coarse_ir_grid_points(primitive,
                              mesh,
                              mesh_divisors,
                              coarse_mesh_shifts,
                              is_kappa_star=True,
                              symprec=1e-5):
    mesh = np.array(mesh, dtype='intc')

    symmetry = Symmetry(primitive, symprec)
    point_group = symmetry.get_pointgroup_operations()

    if mesh_divisors is None:
        (ir_grid_points,
         ir_grid_weights,
         grid_address,
         grid_mapping_table) = get_ir_grid_points(mesh, point_group)
    else:
        mesh_divs = np.array(mesh_divisors, dtype='intc')
        coarse_mesh = mesh // mesh_divs
        if coarse_mesh_shifts is None:
            coarse_mesh_shifts = [False, False, False]
    
        if not is_kappa_star:
            coarse_grid_address = get_grid_address(coarse_mesh)
            coarse_grid_points = np.arange(np.prod(coarse_mesh), dtype='intc')
            coarse_grid_weights = np.ones(len(coarse_grid_points), dtype='intc')
        else:
            (coarse_ir_grid_points,
             coarse_ir_grid_weights,
             coarse_grid_address,
             coarse_grid_mapping_table) = get_ir_grid_points(
                 coarse_mesh,
                 point_group,
                 mesh_shifts=coarse_mesh_shifts)
        ir_grid_points = from_coarse_to_dense_grid_points(
            mesh,
            mesh_divs,
            coarse_grid_points,
            coarse_grid_address,
            coarse_mesh_shifts=coarse_mesh_shifts)
        grid_address = get_grid_address(mesh)
        ir_grid_weights = ir_grid_weights

    primitive_lattice = np.linalg.inv(primitive.get_cell())
    bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address,
                                                           mesh,
                                                           primitive_lattice)

    return (ir_grid_points,
            ir_grid_weights,
            bz_grid_address,
            grid_mapping_table)
示例#24
0
def get_coarse_ir_grid_points(primitive,
                              mesh,
                              mesh_divisors,
                              coarse_mesh_shifts,
                              is_kappa_star=True,
                              symprec=1e-5):
    mesh = np.array(mesh, dtype='intc')

    symmetry = Symmetry(primitive, symprec)
    point_group = symmetry.get_pointgroup_operations()

    if mesh_divisors is None:
        (ir_grid_points,
         ir_grid_weights,
         grid_address,
         grid_mapping_table) = get_ir_grid_points(mesh, point_group)
    else:
        mesh_divs = np.array(mesh_divisors, dtype='intc')
        coarse_mesh = mesh // mesh_divs
        if coarse_mesh_shifts is None:
            coarse_mesh_shifts = [False, False, False]

        if not is_kappa_star:
            coarse_grid_address = get_grid_address(coarse_mesh)
            coarse_grid_points = np.arange(np.prod(coarse_mesh), dtype='uintp')
        else:
            (coarse_ir_grid_points,
             coarse_ir_grid_weights,
             coarse_grid_address,
             coarse_grid_mapping_table) = get_ir_grid_points(
                 coarse_mesh,
                 point_group,
                 mesh_shifts=coarse_mesh_shifts)
        ir_grid_points = from_coarse_to_dense_grid_points(
            mesh,
            mesh_divs,
            coarse_grid_points,
            coarse_grid_address,
            coarse_mesh_shifts=coarse_mesh_shifts)
        grid_address = get_grid_address(mesh)
        ir_grid_weights = ir_grid_weights

    reciprocal_lattice = np.linalg.inv(primitive.get_cell())
    bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address,
                                                           mesh,
                                                           reciprocal_lattice,
                                                           is_dense=True)

    return (ir_grid_points,
            ir_grid_weights,
            bz_grid_address,
            grid_mapping_table)
示例#25
0
def _expand_borns(borns, primitive: PhonopyAtoms, prim_symmetry: Symmetry):
    # Expand Born effective charges to all atoms in the primitive cell
    rotations = prim_symmetry.symmetry_operations["rotations"]
    map_operations = prim_symmetry.get_map_operations()
    map_atoms = prim_symmetry.get_map_atoms()

    for i in range(len(primitive)):
        # R_cart = L R L^-1
        rot_cartesian = similarity_transformation(primitive.cell.T,
                                                  rotations[map_operations[i]])
        # R_cart^T B R_cart^-T (inverse rotation is required to transform)
        borns[i] = similarity_transformation(rot_cartesian.T,
                                             borns[map_atoms[i]])
示例#26
0
 def test_parse_wien2k_struct(self):
     cell, npts, r0s, rmts = parse_wien2k_struct("BaGa2.struct")
     lattice = cell.get_cell().T
     displacements, supercell = parse_disp_yaml("disp_BaGa2.yaml",
                                                return_cell=True)
     symmetry = Symmetry(cell)
     print(PhonopyAtoms(atoms=cell))
     sym_op = symmetry.get_symmetry_operations()
     print(symmetry.get_international_table())
     for i, (r, t) in enumerate(
             zip(sym_op['rotations'], sym_op['translations'])):
         print("--- %d ---" % (i + 1))
         print(r)
         print(t)
示例#27
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
示例#28
0
def get_number_of_triplets(primitive,
                           mesh,
                           grid_point,
                           symprec=1e-5):
    mesh = np.array(mesh, dtype='intc')
    symmetry = Symmetry(primitive, symprec)
    point_group = symmetry.get_pointgroup_operations()
    primitive_lattice = np.linalg.inv(primitive.get_cell())
    triplets_at_q, _, _, _, _, _ = get_triplets_at_q(
        grid_point,
        mesh,
        point_group,
        primitive_lattice)

    return len(triplets_at_q)
示例#29
0
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
示例#30
0
    def __init__(
        self,
        supercell: Supercell,
        primitive: Primitive,
        fc2,
        mesh=None,
        nac_params=None,
        nac_q_direction=None,
        sigmas=None,
        cutoff_frequency=1e-4,
        frequency_step=None,
        num_frequency_points=None,
        num_points_in_batch=None,
        temperatures=None,
        frequency_factor_to_THz=VaspToTHz,
        frequency_scale_factor=None,
        use_grg=False,
        SNF_coordinates="reciprocal",
        is_mesh_symmetry=True,
        is_symmetry=True,
        store_dense_gp_map=False,
        symprec=1e-5,
        output_filename=None,
        log_level=0,
    ):
        """Init method."""
        self._primitive = primitive
        self._supercell = supercell
        self._fc2 = fc2
        self._temperatures = temperatures
        self._nac_params = nac_params
        self._nac_q_direction = nac_q_direction
        if sigmas is None:
            self._sigmas = [None]
        else:
            self._sigmas = sigmas
        self._cutoff_frequency = cutoff_frequency
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._frequency_scale_factor = frequency_scale_factor
        self._is_mesh_symmetry = is_mesh_symmetry
        self._is_symmetry = is_symmetry
        self._store_dense_gp_map = store_dense_gp_map
        self._use_grg = use_grg
        self._SNF_coordinates = SNF_coordinates
        self._symprec = symprec
        self._filename = output_filename
        self._log_level = log_level

        self._bz_grid = None
        self._joint_dos = None
        self._num_frequency_points_in_batch = num_points_in_batch
        self._frequency_step = frequency_step
        self._num_frequency_points = num_frequency_points

        self._primitive_symmetry = Symmetry(self._primitive, self._symprec,
                                            self._is_symmetry)

        if mesh is not None:
            self.mesh_numbers = mesh
            self.initialize(mesh)
示例#31
0
def parse_BORN_from_strings(strings,
                            primitive,
                            symprec=1e-5,
                            is_symmetry=True):
    f = StringIO.StringIO(strings)
    symmetry = Symmetry(primitive, symprec=symprec, is_symmetry=is_symmetry)
    return get_born_parameters(f, primitive, symmetry)
示例#32
0
def get_data(args, interface_mode=None):
    args = parse_args()
    cell, _ = read_crystal_structure(args.filenames[0],
                                     interface_mode=interface_mode)
    f = h5py.File(args.filenames[1])
    primitive_matrix = np.reshape(
        [fracval(x) for x in args.primitive_matrix.split()], (3, 3))
    primitive = get_primitive(cell, primitive_matrix)
    symmetry = Symmetry(primitive)

    data = {}
    data['cell'] = primitive
    data['symmetry'] = symmetry
    data['mesh'] = np.array(f['mesh'][:], dtype='intc')  # (3)
    data['weight'] = f['weight'][:]  # (gp)
    data['group_velocity'] = f['group_velocity'][:]  # (gp, band, 3)
    data['qpoint'] = f['qpoint'][:]  # (gp, 3)
    data['frequency'] = f['frequency'][:]  # (gp, band)
    if 'gamma_N' in f:
        data['gamma_N'] = f['gamma_N'][:]  # (temps, gp, band)
        data['gamma_U'] = f['gamma_U'][:]  # (temps, gp, band)
    if 'gamma_isotope' in f:
        data['gamma_isotope'] = f['gamma_isotope'][:]  # (gp, band)
    data['heat_capacity'] = f['heat_capacity'][:]  # (temps, gp, band)
    data['temperature'] = np.array(f['temperature'][:],
                                   dtype='double')  # (temps)
    ir_grid_points, grid_address, _ = get_grid_symmetry(data)
    data['ir_grid_points'] = ir_grid_points
    data['grid_address'] = grid_address

    return data
示例#33
0
 def _search_phonon_supercell_symmetry(self):
     if self._phonon_supercell_matrix is None:
         self._phonon_supercell_symmetry = self._symmetry
     else:
         self._phonon_supercell_symmetry = Symmetry(self._phonon_supercell,
                                                    self._symprec,
                                                    self._is_symmetry)
示例#34
0
def get_equivalent_q_points_by_symmetry(q_point, structure):

    from phonopy.structure.symmetry import Symmetry
    bulk = PhonopyAtoms(symbols=structure.get_atomic_elements(),
                        scaled_positions=structure.get_scaled_positions(),
                        cell=structure.get_cell().T)

    tot_points = []
    for operation_matrix in Symmetry(bulk).get_reciprocal_operations():
        operation_matrix_q = np.dot(
            np.linalg.inv(structure.get_primitive_matrix()),
            operation_matrix.T)
        operation_matrix_q = np.dot(operation_matrix_q,
                                    structure.get_primitive_matrix())

        q_point_test = np.dot(q_point, operation_matrix_q)

        if (q_point_test >= 0).all():
            tot_points.append(q_point_test)


#    print tot_points
#    print(np.vstack({tuple(row) for row in tot_points}))

    return np.vstack({tuple(row) for row in tot_points})
示例#35
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
示例#36
0
 def _search_primitive_symmetry(self):
     self._primitive_symmetry = Symmetry(self._primitive,
                                         self._symprec,
                                         self._is_symmetry)
     if (len(self._symmetry.get_pointgroup_operations()) !=
         len(self._primitive_symmetry.get_pointgroup_operations())):
         print("Warning: point group symmetries of supercell and primitive"
               "cell are different.")
示例#37
0
    def set_grid(self):
        self._point_operations= get_pointgroup_operations(
                    Symmetry(self._cell).get_pointgroup_operations())
        self._kpoint_operations = get_kpoint_group(self._mesh, self._point_operations)

        (mapping, rot_mappings) =get_mappings(self._mesh,
                                                    Symmetry(self._cell).get_pointgroup_operations(),
                                                    qpoints=np.array([0,0,0],dtype="double"))
        self._rot_mappings = self._kpoint_operations[rot_mappings]
        self._mapping, self._grid=spg.get_ir_reciprocal_mesh(self._mesh, self._cell)
        assert (self._mapping==mapping).all()
        self._map_to_ir_index=np.zeros_like(mapping)
        reverse_mapping=[]
        for i,u in enumerate(np.unique(mapping)):
            reverse_mapping.append(np.where(mapping==u)[0])
            self._map_to_ir_index[np.where(mapping==u)] = i
        self._reverse_mapping=reverse_mapping
示例#38
0
    def __init__(self,
                 mesh,
                 primitive,
                 supercell,
                 fc2,
                 nac_params=None,
                 nac_q_direction=None,
                 sigma=None,
                 cutoff_frequency=None,
                 frequency_step=None,
                 num_frequency_points=None,
                 temperatures=None,
                 frequency_factor_to_THz=VaspToTHz,
                 frequency_scale_factor=1.0,
                 is_nosym=False,
                 symprec=1e-5,
                 filename=None,
                 log_level=False,
                 lapack_zheev_uplo='L'):

        self._grid_point = None
        self._mesh = np.array(mesh, dtype='intc')
        self._primitive = primitive
        self._supercell = supercell
        self._fc2 = fc2
        self._nac_params = nac_params
        self._nac_q_direction = None
        self.set_nac_q_direction(nac_q_direction)
        self._sigma = None
        self.set_sigma(sigma)

        if cutoff_frequency is None:
            self._cutoff_frequency = 0
        else:
            self._cutoff_frequency = cutoff_frequency
        self._frequency_step = frequency_step
        self._num_frequency_points = num_frequency_points
        self._temperatures = temperatures
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._frequency_scale_factor = frequency_scale_factor
        self._is_nosym = is_nosym
        self._symprec = symprec
        self._filename = filename
        self._log_level = log_level
        self._lapack_zheev_uplo = lapack_zheev_uplo

        self._num_band = self._primitive.get_number_of_atoms() * 3
        self._reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
        self._set_dynamical_matrix()
        self._symmetry = Symmetry(primitive, symprec)

        self._tetrahedron_method = None
        self._phonon_done = None
        self._frequencies = None
        self._eigenvectors = None
            
        self._joint_dos = None
        self._frequency_points = None
示例#39
0
def read_castep(filename):
    f_castep = open(filename)
    castep_in = CastepIn(f_castep.readlines())
    f_castep.close()
    tags = castep_in.get_tags()
    # 1st stage is to create Atoms object ignoring Spin polarization. General case.
    cell = Atoms(cell=tags['lattice_vectors'],
                 symbols=tags['atomic_species'],
                 scaled_positions=tags['coordinates'])
    # Analyse spin states and add data to Atoms instance "cell" if ones exist
    magmoms = tags['magnetic_moments']
    if magmoms is not None:
        # Print out symmetry information for magnetic cases
        # Original code from structure/symmetry.py
        symmetry = Symmetry(cell, symprec=1e-5)
        print(
            "CASTEP-interface: Magnetic structure, number of operations without spin: %d"
            % len(symmetry.get_symmetry_operations()['rotations']))
        print("CASTEP-interface: Spacegroup without spin: %s" %
              symmetry.get_international_table())

        cell.set_magnetic_moments(magmoms)
        symmetry = Symmetry(cell, symprec=1e-5)
        print(
            "CASTEP-interface: Magnetic structure, number of operations with spin: %d"
            % len(symmetry.get_symmetry_operations()['rotations']))
        print("")

    return cell
示例#40
0
def read_crystal(filename):
    f_crystal = open(filename)
    crystal_in = CrystalIn(f_crystal.readlines())
    f_crystal.close()
    tags = crystal_in.get_tags()

    cell = Atoms(cell=tags['lattice_vectors'],
                 symbols=tags['atomic_species'],
                 scaled_positions=tags['coordinates'])

    magmoms = tags['magnetic_moments']
    if magmoms is not None:
        # Print out symmetry information for magnetic cases
        # Original code from structure/symmetry.py
        symmetry = Symmetry(cell, symprec=1e-5)
        print(
            "CRYSTAL-interface: Magnetic structure, number of operations without spin: %d"
            % len(symmetry.get_symmetry_operations()['rotations']))
        print("CRYSTAL-interface: Spacegroup without spin: %s" %
              symmetry.get_international_table())

        cell.set_magnetic_moments(magmoms)
        symmetry = Symmetry(cell, symprec=1e-5)
        print(
            "CRYSTAL-interface: Magnetic structure, number of operations with spin: %d"
            % len(symmetry.get_symmetry_operations()['rotations']))
        print("")

    return cell, tags['conv_numbers']
示例#41
0
    def __init__(
        self,
        mesh,
        primitive,
        mass_variances=None,  # length of list is num_atom.
        band_indices=None,
        sigma=None,
        bz_grid=None,
        frequency_factor_to_THz=VaspToTHz,
        use_grg=False,
        store_dense_gp_map=True,
        symprec=1e-5,
        cutoff_frequency=None,
        lapack_zheev_uplo="L",
    ):
        """Init method."""
        self._mesh = mesh
        if mass_variances is None:
            self._mass_variances = get_mass_variances(primitive)
        else:
            self._mass_variances = np.array(mass_variances, dtype="double")
        self._primitive = primitive
        self._sigma = sigma
        self._bz_grid = bz_grid
        self._symprec = symprec
        if cutoff_frequency is None:
            self._cutoff_frequency = 0
        else:
            self._cutoff_frequency = cutoff_frequency
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._lapack_zheev_uplo = lapack_zheev_uplo
        self._nac_q_direction = None

        self._grid_points = None
        self._frequencies = None
        self._eigenvectors = None
        self._phonon_done = None
        self._dm = None
        self._gamma = None
        self._tetrahedron_method = None

        num_band = len(self._primitive) * 3
        if band_indices is None:
            self._band_indices = np.arange(num_band, dtype="int_")
        else:
            self._band_indices = np.array(band_indices, dtype="int_")

        if self._bz_grid is None:
            primitive_symmetry = Symmetry(self._primitive, self._symprec)
            self._bz_grid = BZGrid(
                self._mesh,
                lattice=self._primitive.cell,
                symmetry_dataset=primitive_symmetry.dataset,
                use_grg=use_grg,
                store_dense_gp_map=store_dense_gp_map,
            )
示例#42
0
    def test_get_map_operations(self):
        symprec = 1e-5
        cell = get_unitcell_from_phonopy_yaml("../NaCl.yaml")
        scell = get_supercell(cell, np.diag([2, 2, 2]), symprec=symprec)
        symmetry = Symmetry(scell, symprec=symprec)

        map_ops_cmp = [
            0, 2, 51, 53, 8, 1, 65, 98, 3, 14, 34, 24, 76, 69, 54, 110, 576,
            198, 229, 208, 201, 192, 210, 294, 5, 67, 36, 57, 18, 90, 23, 114,
            0, 9, 1, 96, 6, 323, 98, 326, 3, 42, 17, 293, 16, 130, 99, 337,
            192, 194, 202, 199, 205, 196, 200, 193, 12, 5, 30, 108, 37, 128,
            291, 302
        ]
        start = time.time()
        symmetry._set_map_operations()
        end = time.time()
        # print(end - start)
        map_ops = symmetry.get_map_operations()
        self.assertTrue((map_ops_cmp == map_ops).all())
示例#43
0
    def _search_primitive_symmetry_ideal(self):
        self._primitive_symmetry = Symmetry(self._primitive_ideal,
                                            self._symprec,
                                            self._is_symmetry)

        n0 = len(self._symmetry.get_pointgroup_operations())
        n1 = len(self._primitive_symmetry.get_pointgroup_operations())
        if n0 != n1:
            raise Warning("Point group symmetries of supercell and primitive"
                          "cell are different.")
示例#44
0
文件: crystal.py 项目: gcgs1/phonopy
def get_crystal_structure(cell, conv_numbers, write_symmetry=False):
    lattice = cell.get_cell()
    positions = cell.get_positions()
    numbers = cell.get_atomic_numbers()

    # Create and EXTERNAL file (fort.34)
    # Dimensionality, centring, crystal type
    lines = "3 1 1\n"
    # Cartesian components of the lattice vectors
    for lattvec in lattice:
      lines += ("%12.8f" * 3 + "\n") % tuple(lattvec)

    # Symmetry operators
    if write_symmetry:
        symmetry = Symmetry(cell, symprec=1e-5)
        rotations = symmetry.get_symmetry_operations()['rotations']
        translations = symmetry.get_symmetry_operations()['translations']
        N_symmops = 0
        symmlines = ""
        for i in range(0, len(rotations)):
            N_symmops += 1
            for j in range(0, 3):
                symmlines += ("  %5.2f" * 3 + "\n") % tuple(rotations[i][j])
            symmlines += ("  %5.2f" * 3 + "\n") % tuple(translations[i])

        lines += ("%d\n" % N_symmops)
        lines += symmlines

    else:
        lines += "1\n"
        lines += "  1.00  0.00  0.00\n"
        lines += "  0.00  1.00  0.00\n"
        lines += "  0.00  0.00  1.00\n"
        lines += "  0.00  0.00  0.00\n"

    # Number of atoms in the unit cell (asymmetric unit)
    lines += ("%d\n") % len(positions)
    # Conventional atomic number and cartesian coordinates of the atoms
    for i, pos in zip(conv_numbers, positions):
        lines += ("  %d " + "%16.12f"*3 + "\n") % (i,  pos[0], pos[1], pos[2])

    return lines
示例#45
0
def get_crystal_structure(cell, conv_numbers, write_symmetry=False):
    lattice = cell.get_cell()
    positions = cell.get_positions()
    numbers = cell.get_atomic_numbers()

    # Create and EXTERNAL file (fort.34)
    # Dimensionality, centring, crystal type
    lines = "3 1 1\n"
    # Cartesian components of the lattice vectors
    for lattvec in lattice:
        lines += ("%12.8f" * 3 + "\n") % tuple(lattvec)

    # Symmetry operators
    if write_symmetry:
        symmetry = Symmetry(cell, symprec=1e-5)
        rotations = symmetry.get_symmetry_operations()['rotations']
        translations = symmetry.get_symmetry_operations()['translations']
        N_symmops = 0
        symmlines = ""
        for i in range(0, len(rotations)):
            N_symmops += 1
            for j in range(0, 3):
                symmlines += ("  %5.2f" * 3 + "\n") % tuple(rotations[i][j])
            symmlines += ("  %5.2f" * 3 + "\n") % tuple(translations[i])

        lines += ("%d\n" % N_symmops)
        lines += symmlines

    else:
        lines += "1\n"
        lines += "  1.00  0.00  0.00\n"
        lines += "  0.00  1.00  0.00\n"
        lines += "  0.00  0.00  1.00\n"
        lines += "  0.00  0.00  0.00\n"

    # Number of atoms in the unit cell (asymmetric unit)
    lines += ("%d\n") % len(positions)
    # Conventional atomic number and cartesian coordinates of the atoms
    for i, pos in zip(conv_numbers, positions):
        lines += ("  %d " + "%16.12f" * 3 + "\n") % (i, pos[0], pos[1], pos[2])

    return lines
示例#46
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
示例#47
0
def get_coarse_ir_grid_points(primitive,
                              mesh,
                              mesh_divisors,
                              coarse_mesh_shifts,
                              is_nosym=False,
                              symprec=1e-5):
    if mesh_divisors is None:
        mesh_divs = [1, 1, 1]
    else:
        mesh_divs = mesh_divisors
    mesh = np.array(mesh, dtype='intc')
    mesh_divs = np.array(mesh_divs, dtype='intc')
    coarse_mesh = mesh // mesh_divs
    if coarse_mesh_shifts is None:
        coarse_mesh_shifts = [False, False, False]

    if is_nosym:
        coarse_grid_address = get_grid_address(coarse_mesh)
        coarse_grid_points = np.arange(np.prod(coarse_mesh), dtype='intc')
        coarse_grid_weights = np.ones(len(coarse_grid_points), dtype='intc')
    else:
        symmetry = Symmetry(primitive, symprec)
        (coarse_grid_points,
         coarse_grid_weights,
         coarse_grid_address) = get_ir_grid_points(
             coarse_mesh,
             symmetry.get_pointgroup_operations(),
             mesh_shifts=coarse_mesh_shifts)
    grid_points = from_coarse_to_dense_grid_points(
        mesh,
        mesh_divs,
        coarse_grid_points,
        coarse_grid_address,
        coarse_mesh_shifts=coarse_mesh_shifts)
    grid_address = get_grid_address(mesh)
    primitive_lattice = np.linalg.inv(primitive.get_cell())
    bz_grid_address, _ = spg.relocate_BZ_grid_address(grid_address,
                                                      mesh,
                                                      primitive_lattice)

    return grid_points, coarse_grid_weights, bz_grid_address
示例#48
0
    def set_grid_point(self,
                       grid_point,
                       grid_points2=None,
                       weights2 = None):
        "The grid_point is numbered using the bz scheme"
        self._grid_point = grid_point
        if self._grid_address is None:
            primitive_lattice = np.linalg.inv(self._primitive.get_cell())
            self._grid_address, self._bz_map, self._bz_to_pp_map = get_bz_grid_address(
                self._mesh, primitive_lattice, with_boundary=True, is_bz_map_to_pp=True)

        if grid_points2 is not None:
            self._grid_points2 = grid_points2
            self._weights2 = weights2
        elif not self._is_nosym:
            symmetry = Symmetry(self._primitive, symprec=self._symprec)
            qpoint = self._grid_address[grid_point] / np.double(self._mesh)
            mapping, grid_points = spg.get_stabilized_reciprocal_mesh(self._mesh,
                                                                      symmetry.get_pointgroup_operations(),
                                                                      is_shift=np.zeros(3, dtype='intc'),
                                                                      is_time_reversal=True,
                                                                      qpoints=[qpoint])

            grid_points2 = np.unique(mapping)
            # weight = np.zeros_like(grid_points2)
            # bz_grid_points2 = np.zeros_like(grid_points2)
            # for g, grid in enumerate(grid_points2):
            #     weight[g] = len(np.where(grid == mapping)[0])
            #     bz_grid_points2[g] = np.where(grid == self._bz_to_pp_map)[0][0]
            # self._grid_points2 = bz_grid_points2
            weight_temp = np.bincount(mapping)
            weight = weight_temp[np.nonzero(weight_temp)]
            self._grid_points2 = grid_points2
            self._weights2 = weight
        else:
            self._grid_points2 = np.arange(np.prod(self._mesh))
            self._weights2 = np.ones_like(self._grid_points2, dtype="intc")
示例#49
0
 def test_get_map_operations(self):
     symprec = 1e-5
     cell = get_unitcell_from_phonopy_yaml(
         os.path.join(data_dir,"../NaCl.yaml"))
     scell = get_supercell(cell, np.diag([2, 2, 2]), symprec=symprec)
     symmetry = Symmetry(scell, symprec=symprec)
     start = time.time()
     symmetry._set_map_operations()
     end = time.time()
     # print(end - start)
     map_ops = symmetry.get_map_operations()
     map_atoms = symmetry.get_map_atoms()
     positions = scell.get_scaled_positions()
     rotations = symmetry.get_symmetry_operations()['rotations']
     translations = symmetry.get_symmetry_operations()['translations']
     for i, (op_i, atom_i) in enumerate(zip(map_ops, map_atoms)):
         r_pos = np.dot(rotations[op_i], positions[i]) + translations[op_i]
         diff = positions[atom_i] - r_pos
         diff -= np.rint(diff)
         self.assertTrue((diff < symprec).all())
示例#50
0
class Phonopy:
    def __init__(self,
                 unitcell,
                 supercell_matrix,
                 primitive_matrix=None,
                 nac_params=None,
                 distance=0.01,
                 factor=VaspToTHz,
                 is_auto_displacements=True,
                 dynamical_matrix_decimals=None,
                 force_constants_decimals=None,
                 symprec=1e-5,
                 is_symmetry=True,
                 log_level=0):
        self._symprec = symprec
        self._factor = factor
        self._is_symmetry = is_symmetry
        self._log_level = log_level

        # Create supercell and primitive cell
        self._unitcell = unitcell
        self._supercell_matrix = supercell_matrix
        self._primitive_matrix = primitive_matrix
        self._supercell = None
        self._primitive = None
        self._build_supercell()
        self._build_primitive_cell()

        # Set supercell and primitive symmetry
        self._symmetry = None
        self._primitive_symmetry = None
        self._search_symmetry()
        self._search_primitive_symmetry()

        # set_displacements (used only in preprocess)
        self._displacement_dataset = None
        self._displacements = None
        self._displacement_directions = None
        self._supercells_with_displacements = None
        if is_auto_displacements:
            self.generate_displacements(distance=distance)

        # set_force_constants or set_forces
        self._force_constants = None
        self._force_constants_decimals = force_constants_decimals
        
        # set_dynamical_matrix
        self._dynamical_matrix = None
        self._nac_params = nac_params
        self._dynamical_matrix_decimals = dynamical_matrix_decimals

        # set_band_structure
        self._band_structure = None

        # set_mesh
        self._mesh = None

        # set_tetrahedron_method
        self._tetrahedron_method = None

        # set_thermal_properties
        self._thermal_properties = None

        # set_thermal_displacements
        self._thermal_displacements = None

        # set_thermal_displacement_matrices
        self._thermal_displacement_matrices = None
        
        # set_partial_DOS
        self._pdos = None

        # set_total_DOS
        self._total_dos = None

        # set_modulation
        self._modulation = None

        # set_character_table
        self._irreps = None

        # set_group_velocity
        self._group_velocity = None

    def set_post_process(self,
                         primitive_matrix=None,
                         sets_of_forces=None,
                         displacement_dataset=None,
                         force_constants=None,
                         is_nac=None):
        print 
        print ("********************************** Warning"
               "**********************************")
        print "set_post_process will be obsolete."
        print ("  produce_force_constants is used instead of set_post_process"
               " for producing")
        print ("  force constants from forces.")
        if primitive_matrix is not None:
            print ("  primitive_matrix has to be given at Phonopy::__init__"
                   " object creation.")
        print ("******************************************"
               "**********************************")
        print 

        if primitive_matrix is not None:
            self._primitive_matrix = primitive_matrix
            self._build_primitive_cell()
            self._search_primitive_symmetry()
        
        if sets_of_forces is not None:
            self.set_forces(sets_of_forces)
        elif displacement_dataset is not None:
            self._displacement_dataset = displacement_dataset
        elif force_constants is not None:
            self.set_force_constants(force_constants)
            
        if self._displacement_dataset is not None:
            self.produce_force_constants()

    def set_masses(self, masses):
        p_masses = np.array(masses)
        self._primitive.set_masses(p_masses)
        p2p_map = self._primitive.get_primitive_to_primitive_map()
        s_masses = p_masses[[p2p_map[x] for x in
                             self._primitive.get_supercell_to_primitive_map()]]
        self._supercell.set_masses(s_masses)
        u2s_map = self._supercell.get_unitcell_to_supercell_map()
        u_masses = s_masses[u2s_map]
        self._unitcell.set_masses(u_masses)
        
    def get_primitive(self):
        return self._primitive
    primitive = property(get_primitive)

    def get_unitcell(self):
        return self._unitcell
    unitcell = property(get_unitcell)

    def get_supercell(self):
        return self._supercell
    supercell = property(get_supercell)

    def set_supercell(self, supercell):
        self._supercell = supercell

    def get_symmetry(self):
        """return symmetry of supercell"""
        return self._symmetry
    symmetry = property(get_symmetry)

    def get_primitive_symmetry(self):
        """return symmetry of primitive cell"""
        return self._primitive_symmetry

    def get_unit_conversion_factor(self):
        return self._factor
    unit_conversion_factor = property(get_unit_conversion_factor)

    def produce_force_constants(self,
                                forces=None,
                                calculate_full_force_constants=True,
                                computation_algorithm="svd"):
        if forces is not None:
            self.set_forces(forces)
        
        if calculate_full_force_constants:
            self._run_force_constants_from_forces(
                decimals=self._force_constants_decimals,
                computation_algorithm=computation_algorithm)
        else:
            p2s_map = self._primitive.get_primitive_to_supercell_map()
            self._run_force_constants_from_forces(
                distributed_atom_list=p2s_map,
                decimals=self._force_constants_decimals,
                computation_algorithm=computation_algorithm)

    def set_nac_params(self, nac_params=None, method=None):
        if method is not None:
            print "set_nac_params:"
            print "  Keyword argument of \"method\" is not more supported."
        self._nac_params = nac_params
        
    def generate_displacements(self,
                               distance=0.01,
                               is_plusminus='auto',
                               is_diagonal=True,
                               is_trigonal=False):
        """Generate displacements automatically

        displacemsts: List of displacements in Cartesian coordinates.
           [[0, 0.01, 0.00, 0.00], ...]
        where each set of elements is defined by:
           First value:      Atom index in supercell starting with 0
           Second to fourth: Displacement in Cartesian coordinates
        
        displacement_directions:
          List of directions with respect to axes. This gives only the
          symmetrically non equivalent directions. The format is like:
             [[0, 1, 0, 0],
              [7, 1, 0, 1], ...]
          where each list is defined by:
             First value:      Atom index in supercell starting with 0
             Second to fourth: If the direction is displaced or not ( 1, 0, or -1 )
                               with respect to the axes.
                               
        """
        displacement_directions = get_least_displacements(
            self._symmetry, 
            is_plusminus=is_plusminus,
            is_diagonal=is_diagonal,
            is_trigonal=is_trigonal,
            log_level=self._log_level)
        displacement_dataset = direction_to_displacement(
            displacement_directions,
            distance,
            self._supercell)
        self.set_displacement_dataset(displacement_dataset)

    def set_displacements(self, displacements):
        print 
        print ("********************************** Warning"
               "**********************************")
        print "set_displacements is obsolete. Do nothing."
        print ("******************************************"
               "**********************************")
        print 

    def get_displacements(self):
        return self._displacements
    displacements = property(get_displacements)

    def get_displacement_directions(self):
        return self._displacement_directions
    displacement_directions = property(get_displacement_directions)

    def get_displacement_dataset(self):
        return self._displacement_dataset

    def get_supercells_with_displacements(self):
        if self._displacement_dataset is None:
            return None
        else:
            self._build_supercells_with_displacements()
            return self._supercells_with_displacements

    def get_dynamical_matrix(self):
        return self._dynamical_matrix
    dynamical_matrix = property(get_dynamical_matrix)

    def set_forces(self, sets_of_forces):
        """
        sets_of_forces:
           [[[f_1x, f_1y, f_1z], [f_2x, f_2y, f_2z], ...], # first supercell
             [[f_1x, f_1y, f_1z], [f_2x, f_2y, f_2z], ...], # second supercell
             ...                                                  ]
        """
        for disp, forces in zip(
                self._displacement_dataset['first_atoms'], sets_of_forces):
            disp['forces'] = forces

    def set_force_constants_zero_with_radius(self, cutoff_radius):
        cutoff_force_constants(self._force_constants,
                               self._supercell,
                               cutoff_radius,
                               symprec=self._symprec)

    def set_force_constants(self, force_constants):
        self._force_constants = force_constants

    def set_force_sets(self, force_sets):
        print 
        print ("********************************** Warning"
               "**********************************")
        print "set_force_sets will be obsolete."
        print ("   The method name is changed to set_displacement_dataset.")
        print ("******************************************"
               "**********************************")
        print
        self.set_displacement_dataset(force_sets)

    def set_displacement_dataset(self, displacement_dataset):
        """
        displacement_dataset:
           {'natom': number_of_atoms_in_supercell,
            'first_atoms': [
              {'number': atom index of displaced atom,
               'displacement': displacement in Cartesian coordinates,
               'direction': displacement direction with respect to axes
               'forces': forces on atoms in supercell},
              {...}, ...]}
        """
        self._displacement_dataset = displacement_dataset

        self._displacements = []
        self._displacement_directions = []
        for disp in self._displacement_dataset['first_atoms']:
            x = disp['displacement']
            self._displacements.append([disp['number'], x[0], x[1], x[2]])
            if 'direction' in disp:
                y = disp['direction']
                self._displacement_directions.append(
                    [disp['number'], y[0], y[1], y[2]])
        if not self._displacement_directions:
            self._displacement_directions = None
        
    def symmetrize_force_constants(self, iteration=3):
        symmetrize_force_constants(self._force_constants, iteration)

    def symmetrize_force_constants_by_space_group(self):
        rotations = self._symmetry.get_symmetry_operations()['rotations']
        translations = self._symmetry.get_symmetry_operations()['translations']
        set_tensor_symmetry(self._force_constants,
                            self._supercell.get_cell().T,
                            self._supercell.get_scaled_positions(),
                            rotations,
                            translations,
                            self._symprec)
        
    def get_force_constants(self):
        return self._force_constants
    force_constants = property(get_force_constants)

    def get_rotational_condition_of_fc(self):
        return rotational_invariance(self._force_constants,
                                     self._supercell,
                                     self._primitive,
                                     self._symprec)

    def set_dynamical_matrix(self):
        self._set_dynamical_matrix()
        
    def get_dynamical_matrix_at_q(self, q):
        self._set_dynamical_matrix()
        self._dynamical_matrix.set_dynamical_matrix(q)
        return self._dynamical_matrix.get_dynamical_matrix()

    def get_frequencies(self, q):
        """
        Calculate phonon frequencies at q
        
        q: q-vector in reduced coordinates of primitive cell
        """
        self._set_dynamical_matrix()
        self._dynamical_matrix.set_dynamical_matrix(q)
        dm = self._dynamical_matrix.get_dynamical_matrix()
        frequencies = []
        for eig in np.linalg.eigvalsh(dm).real:
            if eig < 0:
                frequencies.append(-np.sqrt(-eig))
            else:
                frequencies.append(np.sqrt(eig))
            
        return np.array(frequencies) * self._factor

    def get_frequencies_with_eigenvectors(self, q):
        """
        Calculate phonon frequencies and eigenvectors at q
        
        q: q-vector in reduced coordinates of primitive cell
        """
        self._set_dynamical_matrix()
        self._dynamical_matrix.set_dynamical_matrix(q)
        dm = self._dynamical_matrix.get_dynamical_matrix()
        frequencies = []
        eigvals, eigenvectors = np.linalg.eigh(dm)
        frequencies = []
        for eig in eigvals:
            if eig < 0:
                frequencies.append(-np.sqrt(-eig))
            else:
                frequencies.append(np.sqrt(eig))

        return np.array(frequencies) * self._factor, eigenvectors

    def set_band_structure(self,
                           bands,
                           is_eigenvectors=False,
                           is_band_connection=False):
        self._set_dynamical_matrix()
        self._band_structure = BandStructure(
            bands,
            self._dynamical_matrix,
            is_eigenvectors=is_eigenvectors,
            is_band_connection=is_band_connection,
            group_velocity=self._group_velocity,
            factor=self._factor)

    def get_band_structure(self):
        band = self._band_structure
        return (band.get_qpoints(),
                band.get_distances(),                
                band.get_frequencies(),
                band.get_eigenvectors())

    def plot_band_structure(self, symbols=None):
        return self._band_structure.plot_band(symbols)

    def write_yaml_band_structure(self):
        self._band_structure.write_yaml()

    def set_mesh(self,
                 mesh,
                 shift=None,
                 is_time_reversal=True,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_gamma_center=False):
        self._set_dynamical_matrix()
        self._mesh = Mesh(
            self._dynamical_matrix,
            mesh,
            shift=shift,
            is_time_reversal=is_time_reversal,
            is_mesh_symmetry=is_mesh_symmetry,
            is_eigenvectors=is_eigenvectors,
            is_gamma_center=is_gamma_center,
            group_velocity=self._group_velocity,
            rotations=self._primitive_symmetry.get_pointgroup_operations(),
            factor=self._factor)

    def get_mesh(self):
        return (self._mesh.get_qpoints(),
                self._mesh.get_weights(),
                self._mesh.get_frequencies(),
                self._mesh.get_eigenvectors())

    def write_yaml_mesh(self):
        self._mesh.write_yaml()

    def set_thermal_properties(self,
                               t_step=10,
                               t_max=1000,
                               t_min=0,
                               is_projection=False,
                               band_indices=None,
                               cutoff_frequency=None):
        if self._mesh is None:
            print "set_mesh has to be done before set_thermal_properties"
            return False
        else:
            tp = ThermalProperties(self._mesh.get_frequencies(),
                                   weights=self._mesh.get_weights(),
                                   eigenvectors=self._mesh.get_eigenvectors(),
                                   is_projection=is_projection,
                                   band_indices=band_indices,
                                   cutoff_frequency=cutoff_frequency)
            tp.set_thermal_properties(t_step=t_step,
                                      t_max=t_max,
                                      t_min=t_min)
            self._thermal_properties = tp

    def get_thermal_properties(self):
        temps, fe, entropy, cv = \
            self._thermal_properties.get_thermal_properties()
        return temps, fe, entropy, cv

    def plot_thermal_properties(self):
        return self._thermal_properties.plot_thermal_properties()

    def write_yaml_thermal_properties(self, filename='thermal_properties.yaml'):
        self._thermal_properties.write_yaml(filename=filename)

    def set_partial_DOS(self,
                        sigma=None,
                        freq_min=None,
                        freq_max=None,
                        freq_pitch=None,
                        tetrahedron_method=False,
                        direction=None):
        if self._mesh is None:
            print "set_mesh has to be done before set_thermal_properties"
            sys.exit(1)
        if self._mesh.get_eigenvectors() is None:
            print "Eigenvectors have to be calculated."
            sys.exit(1)
        if direction is not None:
            direction_cart = np.dot(direction, self._primitive.get_cell())
        else:
            direction_cart = None
        pdos = PartialDos(self._mesh,
                          sigma=sigma,
                          tetrahedron_method=tetrahedron_method,
                          direction=direction_cart)
        pdos.set_draw_area(freq_min, freq_max, freq_pitch)
        pdos.run()
        self._pdos = pdos

    def get_partial_DOS(self):
        """
        Retern frequencies and partial_dos.
        The first element is freqs and the second is partial_dos.
        
        frequencies: [freq1, freq2, ...]
        partial_dos:
          [[atom1-freq1, atom1-freq2, ...],
           [atom2-freq1, atom2-freq2, ...],
           ...]
        """
        return self._pdos.get_partial_dos()

    def plot_partial_DOS(self, pdos_indices=None, legend=None):
        return self._pdos.plot_pdos(indices=pdos_indices,
                                    legend=legend)

    def write_partial_DOS(self):
        self._pdos.write()

    def set_total_DOS(self,
                      sigma=None,
                      freq_min=None,
                      freq_max=None,
                      freq_pitch=None,
                      tetrahedron_method=False):

        if self._mesh is None:
            print "set_mesh has to be done before set_thermal_properties"
            sys.exit(1)

        total_dos = TotalDos(self._mesh,
                             sigma=sigma,
                             tetrahedron_method=tetrahedron_method)
        total_dos.set_draw_area(freq_min, freq_max, freq_pitch)
        total_dos.run()
        self._total_dos = total_dos

    def get_total_DOS(self):
        """
        Retern frequencies and total dos.
        The first element is freqs and the second is total dos.
        
        frequencies: [freq1, freq2, ...]
        total_dos: [dos1, dos2, ...]
        """
        return self._total_dos.get_dos()

    def set_Debye_frequency(self, freq_max_fit=None):
        self._total_dos.set_Debye_frequency(
            self._primitive.get_number_of_atoms(),
            freq_max_fit=freq_max_fit)

    def get_Debye_frequency(self):
        return self._total_dos.get_Debye_frequency()

    def plot_total_DOS(self):
        return self._total_dos.plot_dos()

    def write_total_DOS(self):
        self._total_dos.write()

    def set_thermal_displacements(self,
                                  t_step=10,
                                  t_max=1000,
                                  t_min=0,
                                  direction=None,
                                  cutoff_frequency=None):
        """
        cutoff_frequency:
          phonon modes that have frequencies below cutoff_frequency
          are ignored.

        direction:
          Projection direction in reduced coordinates
        """
        if self._mesh is None:
            print "set_mesh has to be done before set_thermal_properties"
            sys.exit(1)

        eigvecs = self._mesh.get_eigenvectors()
        frequencies = self._mesh.get_frequencies()
        mesh_nums = self._mesh.get_mesh_numbers() 

        if self._mesh.get_eigenvectors() is None:
            print "Eigenvectors have to be calculated."
            sys.exit(1)
            
        if np.prod(mesh_nums) != len(eigvecs):
            print "Sampling mesh must not be symmetrized."
            sys.exit(1)

        td = ThermalDisplacements(frequencies,
                                  eigvecs,
                                  self._primitive.get_masses(),
                                  cutoff_frequency=cutoff_frequency)
        td.set_temperature_range(t_min, t_max, t_step)
        if direction is not None:
            td.project_eigenvectors(direction, self._primitive.get_cell())
        td.run()
        
        self._thermal_displacements = td

    def get_thermal_displacements(self):
        if self._thermal_displacements is not None:
            return self._thermal_displacements.get_thermal_displacements()
        
    def plot_thermal_displacements(self, is_legend=False):
        return self._thermal_displacements.plot(is_legend)

    def write_yaml_thermal_displacements(self):
        self._thermal_displacements.write_yaml()

    def set_thermal_displacement_matrices(self,
                                           t_step=10,
                                           t_max=1000,
                                           t_min=0,
                                           cutoff_frequency=None):
        """
        cutoff_frequency:
          phonon modes that have frequencies below cutoff_frequency
          are ignored.

        direction:
          Projection direction in reduced coordinates
        """
        if self._mesh is None:
            print "set_mesh has to be done before set_thermal_properties"
            sys.exit(1)

        eigvecs = self._mesh.get_eigenvectors()
        frequencies = self._mesh.get_frequencies()
        mesh_nums = self._mesh.get_mesh_numbers() 

        if self._mesh.get_eigenvectors() is None:
            print "Eigenvectors have to be calculated."
            sys.exit(1)
            
        if np.prod(mesh_nums) != len(eigvecs):
            print "Sampling mesh must not be symmetrized."
            sys.exit(1)

        tdm = ThermalDisplacementMatrices(frequencies,
                                           eigvecs,
                                           self._primitive.get_masses(),
                                           cutoff_frequency=cutoff_frequency)
        tdm.set_temperature_range(t_min, t_max, t_step)
        tdm.run()
        
        self._thermal_displacement_matrices = tdm

    def get_thermal_displacement_matrices(self):
        if self._thermal_displacement_matrices is not None:
            return self._thermal_displacement_matrices.get_thermal_displacement_matrices()
        
    def write_yaml_thermal_displacement_matrices(self):
        self._thermal_displacement_matrices.write_yaml()
        
    def set_thermal_distances(self,
                              atom_pairs,
                              t_step=10,
                              t_max=1000,
                              t_min=0,
                              cutoff_frequency=None):
        """
        atom_pairs: List of list
          Mean square distances are calculated for the atom_pairs
          e.g. [[1, 2], [1, 4]]

        cutoff_frequency:
          phonon modes that have frequencies below cutoff_frequency
          are ignored.
        """

        td = ThermalDistances(self._mesh.get_frequencies(),
                              self._mesh.get_eigenvectors(),
                              self._supercell,
                              self._primitive,
                              self._mesh.get_qpoints(),
                              cutoff_frequency=cutoff_frequency)
        td.set_temperature_range(t_min, t_max, t_step)
        td.run(atom_pairs)

        self._thermal_distances = td

    def write_yaml_thermal_distances(self):
        self._thermal_distances.write_yaml()

    def set_qpoints_phonon(self,
                           q_points,
                           nac_q_direction=None,
                           is_eigenvectors=False,
                           write_dynamical_matrices=False,
                           factor=VaspToTHz):
        self._set_dynamical_matrix()
        self._qpoints_phonon = QpointsPhonon(
            q_points,
            self._dynamical_matrix,
            nac_q_direction=nac_q_direction,
            is_eigenvectors=is_eigenvectors,
            group_velocity=self._group_velocity,
            write_dynamical_matrices=write_dynamical_matrices,
            factor=self._factor)
        
    def get_qpoints_phonon(self):
        return (self._qpoints_phonon.get_frequencies(),
                self._qpoints_phonon.get_eigenvectors())
    
    def write_yaml_qpoints_phonon(self):
        self._qpoints_phonon.write_yaml()

    def write_animation(self,
                        q_point=None,
                        anime_type='v_sim',
                        band_index=None,
                        amplitude=None,
                        num_div=None,
                        shift=None,
                        filename=None):
        self._set_dynamical_matrix()
        if q_point is None:
            animation = Animation([0, 0, 0],
                                  self._dynamical_matrix,
                                  shift=shift)
        else:
            animation = Animation(q_point,
                                  self._dynamical_matrix,
                                  shift=shift)
        if anime_type == 'v_sim':
            if amplitude:
                amplitude_ = amplitude
            else:
                amplitude_ = 1.0

            if filename:
                animation.write_v_sim(amplitude=amplitude_,
                                      factor=self._factor,
                                      filename=filename)
            else:
                animation.write_v_sim(amplitude=amplitude_,
                                      factor=self._factor)

            
        if (anime_type == 'arc' or
            anime_type == 'xyz' or
            anime_type == 'jmol' or
            anime_type == 'poscar'):
            if band_index is None or amplitude is None or num_div is None:
                print "Parameters are not correctly set for animation."
                sys.exit(1)

            if anime_type == 'arc' or anime_type is None:
                if filename:
                    animation.write_arc(band_index,
                                        amplitude,
                                        num_div,
                                        filename=filename)
                else:
                    animation.write_arc(band_index,
                                        amplitude,
                                        num_div)
    
            if anime_type == 'xyz':
                if filename:
                    animation.write_xyz(band_index,
                                        amplitude,
                                        num_div,
                                        self._factor,
                                        filename=filename)
                else:
                    animation.write_xyz(band_index,
                                        amplitude,
                                        num_div,
                                        self._factor)
    
            if anime_type == 'jmol':
                if filename:
                    animation.write_xyz_jmol(amplitude=amplitude,
                                             factor=self._factor,
                                             filename=filename)
                else:
                    animation.write_xyz_jmol(amplitude=amplitude,
                                             factor=self._factor)
    
            if anime_type == 'poscar':
                if filename:
                    animation.write_POSCAR(band_index,
                                           amplitude,
                                           num_div,
                                           filename=filename)
                else:
                    animation.write_POSCAR(band_index,
                                           amplitude,
                                           num_div)
                    
    def set_modulations(self,
                        dimension,
                        phonon_modes,
                        delta_q=None,
                        derivative_order=None,
                        nac_q_direction=None):
        self._set_dynamical_matrix()
        self._modulation = Modulation(self._dynamical_matrix,
                                      dimension,
                                      phonon_modes,
                                      delta_q=delta_q,
                                      derivative_order=derivative_order,
                                      nac_q_direction=nac_q_direction,
                                      factor=self._factor)
        self._modulation.run()
                    
    def get_modulations(self):
        """Returns cells with modulations as Atoms objects"""
        return self._modulation.get_modulations()
                
    def get_delta_modulations(self):
        """Return modulations relative to equilibrium supercell

        (modulations, supercell)

        modulations: Atomic modulations of supercell in Cartesian coordinates
        supercell: Supercell as an Atoms object.
        
        """
        return self._modulation.get_delta_modulations()
                
    def write_modulations(self):
        """Create MPOSCAR's"""
        self._modulation.write()
                          
    def write_yaml_modulations(self):
        self._modulation.write_yaml()

    def set_irreps(self,
                   q,
                   is_little_cogroup=False,
                   nac_q_direction=None,
                   degeneracy_tolerance=1e-4):
        self._set_dynamical_matrix()
        self._irreps = IrReps(
            self._dynamical_matrix,
            q,
            is_little_cogroup=is_little_cogroup,
            nac_q_direction=nac_q_direction,
            factor=self._factor,
            symprec=self._symprec,
            degeneracy_tolerance=degeneracy_tolerance,
            log_level=self._log_level)

        return self._irreps.run()

    def get_irreps(self):
        return self._irreps
        
    def show_irreps(self, show_irreps=False):
        self._irreps.show(show_irreps=show_irreps)

    def write_yaml_irreps(self, show_irreps=False):
        self._irreps.write_yaml(show_irreps=show_irreps)

    def set_group_velocity(self, q_length=None):
        self._set_dynamical_matrix()
        self._group_velocity = GroupVelocity(
            self._dynamical_matrix,
            q_length=q_length,
            symmetry=self._primitive_symmetry,
            frequency_factor_to_THz=self._factor)

    def get_group_velocity(self):
        return self._group_velocity.get_group_velocity()
        
    def get_group_velocity_at_q(self, q_point):
        if self._group_velocity is None:
            self.set_group_velocity()
        self._group_velocity.set_q_points([q_point])
        return self._group_velocity.get_group_velocity()[0]

    def _run_force_constants_from_forces(self,
                                         distributed_atom_list=None,
                                         decimals=None,
                                         computation_algorithm="svd"):
        if self._displacement_dataset is not None:
            self._force_constants = get_fc2(
                self._supercell,
                self._symmetry,
                self._displacement_dataset,
                atom_list=distributed_atom_list,
                decimals=decimals,
                computation_algorithm=computation_algorithm)

    def _set_dynamical_matrix(self):
        if self._nac_params is None:
            self._dynamical_matrix = DynamicalMatrix(
                self._supercell,
                self._primitive,
                self._force_constants,
                decimals=self._dynamical_matrix_decimals,
                symprec=self._symprec)
        else:
            self._dynamical_matrix = DynamicalMatrixNAC(
                self._supercell,
                self._primitive,
                self._force_constants,
                nac_params=self._nac_params,
                decimals=self._dynamical_matrix_decimals,
                symprec=self._symprec)

    def _search_symmetry(self):
        self._symmetry = Symmetry(self._supercell,
                                  self._symprec,
                                  self._is_symmetry)

    def _search_primitive_symmetry(self):
        self._primitive_symmetry = Symmetry(self._primitive,
                                            self._symprec,
                                            self._is_symmetry)
        
        if (len(self._symmetry.get_pointgroup_operations()) !=
            len(self._primitive_symmetry.get_pointgroup_operations())):
            print ("Warning: point group symmetries of supercell and primitive"
                   "cell are different.")

    def _build_supercell(self):
        self._supercell = get_supercell(self._unitcell,
                                        self._supercell_matrix,
                                        self._symprec)

    def _build_supercells_with_displacements(self):
        supercells = []
        for disp in self._displacement_dataset['first_atoms']:
            positions = self._supercell.get_positions()
            positions[disp['number']] += disp['displacement']
            supercells.append(Atoms(
                    numbers=self._supercell.get_atomic_numbers(),
                    masses=self._supercell.get_masses(),
                    magmoms=self._supercell.get_magnetic_moments(),
                    positions=positions,
                    cell=self._supercell.get_cell(),
                    pbc=True))

        self._supercells_with_displacements = supercells

    def _build_primitive_cell(self):
        """
        primitive_matrix:
          Relative axes of primitive cell to the input unit cell.
          Relative axes to the supercell is calculated by:
             supercell_matrix^-1 * primitive_matrix
          Therefore primitive cell lattice is finally calculated by:
             (supercell_lattice * (supercell_matrix)^-1 * primitive_matrix)^T
        """

        inv_supercell_matrix = np.linalg.inv(self._supercell_matrix)
        if self._primitive_matrix is None:
            trans_mat = inv_supercell_matrix
        else:
            trans_mat = np.dot(inv_supercell_matrix, self._primitive_matrix)
        self._primitive = get_primitive(
            self._supercell, trans_mat, self._symprec)
        num_satom = self._supercell.get_number_of_atoms()
        num_patom = self._primitive.get_number_of_atoms()
        if abs(num_satom * np.linalg.det(trans_mat) - num_patom) < 0.1:
            return True
        else:
            return False
示例#51
0
class Phono3py:
    def __init__(self,
                 unitcell,
                 supercell_matrix,
                 primitive_matrix=None,
                 phonon_supercell_matrix=None,
                 masses=None,
                 mesh=None,
                 band_indices=None,
                 sigmas=None,
                 cutoff_frequency=1e-4,
                 frequency_factor_to_THz=VaspToTHz,
                 is_symmetry=True,
                 is_nosym=False,
                 symmetrize_fc3_q=False,
                 symprec=1e-5,
                 log_level=0,
                 lapack_zheev_uplo='L'):
        if sigmas is None:
            sigmas = []
        self._symprec = symprec
        self._sigmas = sigmas
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._is_symmetry = is_symmetry
        self._is_nosym = is_nosym
        self._lapack_zheev_uplo =  lapack_zheev_uplo
        self._symmetrize_fc3_q = symmetrize_fc3_q
        self._cutoff_frequency = cutoff_frequency
        self._log_level = log_level

        # Create supercell and primitive cell
        self._unitcell = unitcell
        self._supercell_matrix = supercell_matrix
        self._primitive_matrix = primitive_matrix
        self._phonon_supercell_matrix = phonon_supercell_matrix # optional
        self._supercell = None
        self._primitive = None
        self._phonon_supercell = None
        self._phonon_primitive = None
        self._build_supercell()
        self._build_primitive_cell()
        self._build_phonon_supercell()
        self._build_phonon_primitive_cell()

        if masses is not None:
            self._set_masses(masses)

        # Set supercell, primitive, and phonon supercell symmetries
        self._symmetry = None
        self._primitive_symmetry = None
        self._phonon_supercell_symmetry = None
        self._search_symmetry()
        self._search_primitive_symmetry()
        self._search_phonon_supercell_symmetry()

        # Displacements and supercells
        self._supercells_with_displacements = None
        self._displacement_dataset = None
        self._phonon_displacement_dataset = None
        self._phonon_supercells_with_displacements = None
                
        # Thermal conductivity
        self._thermal_conductivity = None # conductivity_RTA object

        # Imaginary part of self energy at frequency points
        self._imag_self_energy = None
        self._scattering_event_class = None

        # Linewidth (Imaginary part of self energy x 2) at temperatures
        self._linewidth = None

        self._grid_points = None
        self._frequency_points = None
        self._temperatures = None

        # Other variables
        self._fc2 = None
        self._fc3 = None
        
        # Setup interaction
        self._interaction = None
        self._mesh = None
        self._band_indices = None
        self._band_indices_flatten = None
        if mesh is not None:
            self._mesh = np.array(mesh, dtype='intc')
        self.set_band_indices(band_indices)

    def set_band_indices(self, band_indices):
        if band_indices is None:
            num_band = self._primitive.get_number_of_atoms() * 3
            self._band_indices = [np.arange(num_band, dtype='intc')]
        else:
            self._band_indices = band_indices
        self._band_indices_flatten = np.hstack(self._band_indices).astype('intc')

    def set_phph_interaction(self,
                             nac_params=None,
                             nac_q_direction=None,
                             constant_averaged_interaction=None,
                             frequency_scale_factor=None,
                             unit_conversion=None):
        self._interaction = Interaction(
            self._supercell,
            self._primitive,
            self._mesh,
            self._primitive_symmetry,
            fc3=self._fc3,
            band_indices=self._band_indices_flatten,
            constant_averaged_interaction=constant_averaged_interaction,
            frequency_factor_to_THz=self._frequency_factor_to_THz,
            unit_conversion=unit_conversion,
            cutoff_frequency=self._cutoff_frequency,
            is_nosym=self._is_nosym,
            symmetrize_fc3_q=self._symmetrize_fc3_q,
            lapack_zheev_uplo=self._lapack_zheev_uplo)
        self._interaction.set_dynamical_matrix(
            self._fc2,
            self._phonon_supercell,
            self._phonon_primitive,
            nac_params=nac_params,
            frequency_scale_factor=frequency_scale_factor)
        self._interaction.set_nac_q_direction(nac_q_direction=nac_q_direction)

    def generate_displacements(self,
                               distance=0.03,
                               cutoff_pair_distance=None,
                               is_plusminus='auto',
                               is_diagonal=True):
        direction_dataset = get_third_order_displacements(
            self._supercell,
            self._symmetry,
            is_plusminus=is_plusminus,
            is_diagonal=is_diagonal)
        self._displacement_dataset = direction_to_displacement(
            direction_dataset,
            distance,
            self._supercell,
            cutoff_distance=cutoff_pair_distance)

        if self._phonon_supercell_matrix is not None:
            phonon_displacement_directions = get_least_displacements(
                self._phonon_supercell_symmetry,
                is_plusminus=is_plusminus,
                is_diagonal=False)
            self._phonon_displacement_dataset = direction_to_displacement_fc2(
                phonon_displacement_directions,
                distance,
                self._phonon_supercell)
            
    def produce_fc2(self,
                    forces_fc2,
                    displacement_dataset=None,
                    is_permutation_symmetry=False,
                    translational_symmetry_type=0):
        if displacement_dataset is None:
            disp_dataset = self._displacement_dataset
        else:
            disp_dataset = displacement_dataset
            
        for forces, disp1 in zip(forces_fc2, disp_dataset['first_atoms']):
            disp1['forces'] = forces
        self._fc2 = get_fc2(self._phonon_supercell,
                            self._phonon_supercell_symmetry,
                            disp_dataset)
        if is_permutation_symmetry:
            set_permutation_symmetry(self._fc2)
        if translational_symmetry_type:
            set_translational_invariance(
                self._fc2,
                translational_symmetry_type=translational_symmetry_type)

    def produce_fc3(self,
                    forces_fc3,
                    displacement_dataset=None,
                    cutoff_distance=None, # set fc3 zero
                    translational_symmetry_type=0,
                    is_permutation_symmetry=False,
                    is_permutation_symmetry_fc2=False):
        if displacement_dataset is None:
            disp_dataset = self._displacement_dataset
        else:
            disp_dataset = displacement_dataset
        
        for forces, disp1 in zip(forces_fc3, disp_dataset['first_atoms']):
            disp1['forces'] = forces
        fc2 = get_fc2(self._supercell, self._symmetry, disp_dataset)
        if is_permutation_symmetry_fc2:
            set_permutation_symmetry(fc2)
        if translational_symmetry_type:
            set_translational_invariance(
                fc2,
                translational_symmetry_type=translational_symmetry_type)
        
        count = len(disp_dataset['first_atoms'])
        for disp1 in disp_dataset['first_atoms']:
            for disp2 in disp1['second_atoms']:
                disp2['delta_forces'] = forces_fc3[count] - disp1['forces']
                count += 1
        self._fc3 = get_fc3(
            self._supercell,
            disp_dataset,
            fc2,
            self._symmetry,
            translational_symmetry_type=translational_symmetry_type,
            is_permutation_symmetry=is_permutation_symmetry,
            verbose=self._log_level)

        # Set fc3 elements zero beyond cutoff_distance
        if cutoff_distance:
            if self._log_level:
                print("Cutting-off fc3 by zero (cut-off distance: %f)" %
                      cutoff_distance)
            self.cutoff_fc3_by_zero(cutoff_distance)

        # Set fc2
        if self._fc2 is None:
            self._fc2 = fc2

    def cutoff_fc3_by_zero(self, cutoff_distance):
        cutoff_fc3_by_zero(self._fc3,
                           self._supercell,
                           cutoff_distance,
                           self._symprec)
            
    def set_permutation_symmetry(self):
        if self._fc2 is not None:
            set_permutation_symmetry(self._fc2)
        if self._fc3 is not None:
            set_permutation_symmetry_fc3(self._fc3)

    def set_translational_invariance(self,
                                     translational_symmetry_type=1):
        if self._fc2 is not None:
            set_translational_invariance(
                self._fc2,
                translational_symmetry_type=translational_symmetry_type)
        if self._fc3 is not None:
            set_translational_invariance_fc3(
                self._fc3,
                translational_symmetry_type=translational_symmetry_type)
        
    def get_interaction_strength(self):
        return self._interaction
        
    def get_fc2(self):
        return self._fc2

    def set_fc2(self, fc2):
        self._fc2 = fc2

    def get_fc3(self):
        return self._fc3

    def set_fc3(self, fc3):
        self._fc3 = fc3

    def get_primitive(self):
        return self._primitive

    def get_unitcell(self):
        return self._unitcell

    def get_supercell(self):
        return self._supercell

    def get_phonon_supercell(self):
        return self._phonon_supercell

    def get_phonon_primitive(self):
        return self._phonon_primitive

    def get_symmetry(self):
        """return symmetry of supercell"""
        return self._symmetry

    def get_primitive_symmetry(self):
        return self._primitive_symmetry

    def get_phonon_supercell_symmetry(self):
        return self._phonon_supercell_symmetry
        
    def set_displacement_dataset(self, dataset):
        self._displacement_dataset = dataset
        
    def get_displacement_dataset(self):
        return self._displacement_dataset

    def get_phonon_displacement_dataset(self):
        return self._phonon_displacement_dataset

    def get_supercells_with_displacements(self):
        if self._supercells_with_displacements is None:
            self._build_supercells_with_displacements()
        return self._supercells_with_displacements

    def get_phonon_supercells_with_displacements(self):
        if self._phonon_supercells_with_displacements is None:
            if self._phonon_displacement_dataset is not None:
                self._phonon_supercells_with_displacements = \
                  self._build_phonon_supercells_with_displacements(
                      self._phonon_supercell,
                      self._phonon_displacement_dataset)
        return self._phonon_supercells_with_displacements
        
    def run_imag_self_energy(self,
                             grid_points,
                             frequency_step=None,
                             num_frequency_points=None,
                             temperatures=None,
                             scattering_event_class=None,
                             run_with_g=True,
                             write_details=False):
        if temperatures is None:
            temperatures = [0.0, 300.0]
        self._grid_points = grid_points
        self._temperatures = temperatures
        self._scattering_event_class = scattering_event_class
        self._imag_self_energy, self._frequency_points = get_imag_self_energy(
            self._interaction,
            grid_points,
            self._sigmas,
            frequency_step=frequency_step,
            num_frequency_points=num_frequency_points,
            temperatures=temperatures,
            scattering_event_class=scattering_event_class,
            run_with_g=run_with_g,
            write_details=write_details,
            log_level=self._log_level)
            
    def write_imag_self_energy(self, filename=None):
        write_imag_self_energy(
            self._imag_self_energy,
            self._mesh,
            self._grid_points,
            self._band_indices,
            self._frequency_points,
            self._temperatures,
            self._sigmas,
            scattering_event_class=self._scattering_event_class,
            filename=filename)
        
    def run_linewidth(self,
                      grid_points,
                      temperatures=np.arange(0, 1001, 10, dtype='double'),
                      run_with_g=True,
                      write_details=False):
        self._grid_points = grid_points
        self._temperatures = temperatures
        self._linewidth = get_linewidth(self._interaction,
                                        grid_points,
                                        self._sigmas,
                                        temperatures=temperatures,
                                        run_with_g=run_with_g,
                                        write_details=write_details,
                                        log_level=self._log_level)

    def write_linewidth(self, filename=None):
        write_linewidth(self._linewidth,
                        self._band_indices,
                        self._mesh,
                        self._grid_points,
                        self._sigmas,
                        self._temperatures,
                        filename=filename)

    def run_thermal_conductivity(
            self,
            is_LBTE=True,
            temperatures=np.arange(0, 1001, 10, dtype='double'),
            sigmas=None,
            is_isotope=False,
            mass_variances=None,
            grid_points=None,
            boundary_mfp=None, # in micrometre
            use_averaged_pp_interaction=False,
            gamma_unit_conversion=None,
            mesh_divisors=None,
            coarse_mesh_shifts=None,
            is_reducible_collision_matrix=False,
            no_kappa_stars=False,
            gv_delta_q=None, # for group velocity
            run_with_g=True, # integration weights for smearing method, too
            pinv_cutoff=1.0e-8, # for pseudo-inversion of collision matrix
            write_gamma=False,
            read_gamma=False,
            write_collision=False,
            read_collision=False,
            write_amplitude=False,
            read_amplitude=False,
            input_filename=None,
            output_filename=None):

        if sigmas is None:
            sigmas = []
        if is_LBTE:
            self._thermal_conductivity = get_thermal_conductivity_LBTE(
                self._interaction,
                self._primitive_symmetry,
                temperatures=temperatures,
                sigmas=self._sigmas,
                is_isotope=is_isotope,
                mass_variances=mass_variances,
                grid_points=grid_points,
                boundary_mfp=boundary_mfp,
                is_reducible_collision_matrix=is_reducible_collision_matrix,
                no_kappa_stars=no_kappa_stars,
                gv_delta_q=gv_delta_q,
                pinv_cutoff=pinv_cutoff,
                write_collision=write_collision,
                read_collision=read_collision,
                input_filename=input_filename,
                output_filename=output_filename,
                log_level=self._log_level)
        else:
            self._thermal_conductivity = get_thermal_conductivity_RTA(
                self._interaction,
                self._primitive_symmetry,
                temperatures=temperatures,
                sigmas=self._sigmas,
                is_isotope=is_isotope,
                mass_variances=mass_variances,
                grid_points=grid_points,
                boundary_mfp=boundary_mfp,
                use_averaged_pp_interaction=use_averaged_pp_interaction,
                gamma_unit_conversion=gamma_unit_conversion,
                mesh_divisors=mesh_divisors,
                coarse_mesh_shifts=coarse_mesh_shifts,
                no_kappa_stars=no_kappa_stars,
                gv_delta_q=gv_delta_q,
                run_with_g=run_with_g,
                write_gamma=write_gamma,
                read_gamma=read_gamma,
                input_filename=input_filename,
                output_filename=output_filename,
                log_level=self._log_level)

    def get_thermal_conductivity(self):
        return self._thermal_conductivity

    def get_frequency_shift(self,
                            grid_points,
                            epsilons=None,
                            temperatures=np.arange(0, 1001, 10, dtype='double'),
                            output_filename=None):
        if epsilons is None:
            epsilons = [0.1]
        self._grid_points = grid_points
        get_frequency_shift(self._interaction,
                            self._grid_points,
                            self._band_indices,
                            epsilons,
                            temperatures,
                            output_filename=output_filename,
                            log_level=self._log_level)

    def _search_symmetry(self):
        self._symmetry = Symmetry(self._supercell,
                                  self._symprec,
                                  self._is_symmetry)

    def _search_primitive_symmetry(self):
        self._primitive_symmetry = Symmetry(self._primitive,
                                            self._symprec,
                                            self._is_symmetry)
        if (len(self._symmetry.get_pointgroup_operations()) !=
            len(self._primitive_symmetry.get_pointgroup_operations())):
            print("Warning: point group symmetries of supercell and primitive"
                  "cell are different.")
        
    def _search_phonon_supercell_symmetry(self):
        if self._phonon_supercell_matrix is None:
            self._phonon_supercell_symmetry = self._symmetry
        else:
            self._phonon_supercell_symmetry = Symmetry(self._phonon_supercell,
                                                       self._symprec,
                                                       self._is_symmetry)

    def _build_supercell(self):
        self._supercell = get_supercell(self._unitcell,
                                        self._supercell_matrix,
                                        self._symprec)

    def _build_primitive_cell(self):
        """
        primitive_matrix:
          Relative axes of primitive cell to the input unit cell.
          Relative axes to the supercell is calculated by:
             supercell_matrix^-1 * primitive_matrix
          Therefore primitive cell lattice is finally calculated by:
             (supercell_lattice * (supercell_matrix)^-1 * primitive_matrix)^T
        """
        self._primitive = self._get_primitive_cell(
            self._supercell, self._supercell_matrix, self._primitive_matrix)

    def _build_phonon_supercell(self):
        """
        phonon_supercell:
          This supercell is used for harmonic phonons (frequencies,
          eigenvectors, group velocities, ...)
        phonon_supercell_matrix:
          Different supercell size can be specified.
        """
        if self._phonon_supercell_matrix is None:
            self._phonon_supercell = self._supercell
        else:
            self._phonon_supercell = get_supercell(
                self._unitcell, self._phonon_supercell_matrix, self._symprec)

    def _build_phonon_primitive_cell(self):
        if self._phonon_supercell_matrix is None:
            self._phonon_primitive = self._primitive
        else:
            self._phonon_primitive = self._get_primitive_cell(
                self._phonon_supercell,
                self._phonon_supercell_matrix,
                self._primitive_matrix)
            if self._primitive is not None:
                if (self._primitive.get_atomic_numbers() !=
                    self._phonon_primitive.get_atomic_numbers()).any():
                    print("********************* Warning *********************")
                    print(" Primitive cells for fc2 and fc3 can be different.")
                    print("********************* Warning *********************")


    def _build_phonon_supercells_with_displacements(self,
                                                    supercell,
                                                    displacement_dataset):
        supercells = []
        magmoms = supercell.get_magnetic_moments()
        masses = supercell.get_masses()
        numbers = supercell.get_atomic_numbers()
        lattice = supercell.get_cell()
        
        for disp1 in displacement_dataset['first_atoms']:
            disp_cart1 = disp1['displacement']
            positions = supercell.get_positions()
            positions[disp1['number']] += disp_cart1
            supercells.append(
                Atoms(numbers=numbers,
                      masses=masses,
                      magmoms=magmoms,
                      positions=positions,
                      cell=lattice,
                      pbc=True))

        return supercells
            
    def _build_supercells_with_displacements(self):
        supercells = []
        magmoms = self._supercell.get_magnetic_moments()
        masses = self._supercell.get_masses()
        numbers = self._supercell.get_atomic_numbers()
        lattice = self._supercell.get_cell()
        
        supercells = self._build_phonon_supercells_with_displacements(
            self._supercell,
            self._displacement_dataset)
        
        for disp1 in self._displacement_dataset['first_atoms']:
            disp_cart1 = disp1['displacement']
            for disp2 in disp1['second_atoms']:
                if 'included' in disp2:
                    included = disp2['included']
                else:
                    included = True
                if included:
                    positions = self._supercell.get_positions()
                    positions[disp1['number']] += disp_cart1
                    positions[disp2['number']] += disp2['displacement']
                    supercells.append(Atoms(numbers=numbers,
                                            masses=masses,
                                            magmoms=magmoms,
                                            positions=positions,
                                            cell=lattice,
                                            pbc=True))
                else:
                    supercells.append(None)

        self._supercells_with_displacements = supercells
            
    def _get_primitive_cell(self, supercell, supercell_matrix, primitive_matrix):
        inv_supercell_matrix = np.linalg.inv(supercell_matrix)
        if primitive_matrix is None:
            t_mat = inv_supercell_matrix
        else:
            t_mat = np.dot(inv_supercell_matrix, primitive_matrix)
            
        return get_primitive(supercell, t_mat, self._symprec)

    def _set_masses(self, masses):
        p_masses = np.array(masses)
        self._primitive.set_masses(p_masses)
        p2p_map = self._primitive.get_primitive_to_primitive_map()
        s_masses = p_masses[[p2p_map[x] for x in
                             self._primitive.get_supercell_to_primitive_map()]]
        self._supercell.set_masses(s_masses)
        u2s_map = self._supercell.get_unitcell_to_supercell_map()
        u_masses = s_masses[u2s_map]
        self._unitcell.set_masses(u_masses)

        self._phonon_primitive.set_masses(p_masses)
        p2p_map = self._phonon_primitive.get_primitive_to_primitive_map()
        s_masses = p_masses[
            [p2p_map[x] for x in
             self._phonon_primitive.get_supercell_to_primitive_map()]]
        self._phonon_supercell.set_masses(s_masses)
示例#52
0
文件: abinit.py 项目: gcgs1/phonopy
        self._set_x_tags('xred')

    def _set_x_tags(self, tagname):
        xtag = []
        natom = self._tags['natom']
        for val in self._values:
            xtag += self._get_numerical_values(val)
            if len(xtag) >= natom * 3:
                break

        self._tags[tagname] = np.reshape(xtag[:natom * 3], (-1, 3))

    def _set_znucl(self):
        znucl = []
        ntypat = self._tags['ntypat']
        for val in self._values:
            znucl += self._get_numerical_values(val, num_type='int')
            if len(znucl) >= ntypat:
                break

        self._tags['znucl'] = znucl[:ntypat]

if __name__ == '__main__':
    import sys
    from phonopy.structure.symmetry import Symmetry
    abinit = AbinitIn(open(sys.argv[1]).readlines())
    cell = read_abinit(sys.argv[1])
    symmetry = Symmetry(cell)
    print("# %s" % symmetry.get_international_table())
    print(get_abinit_structure(cell))
示例#53
0
文件: lmto.py 项目: gcgs1/phonopy
        self._tags['plat'] = plat

    def _set_alat(self, header):
        hlist = header.split()
        for j in hlist:
            if j.startswith('alat'):
                alat = float(j.split('=')[1])
                break
        self._tags['alat'] = alat    

    def _check_ord(self, header):
        if not 'xpos' in header.split():
            print('EXIT(1): LMTO Interface requires site', end=' ')
            print('files to be in fractional co-ordinates')
            sys.exit(1)
            
    def get_variables(self, header, sites):
        self._check_ord(header)
        self._set_atoms(sites)
        self._set_plat(header)
        self._set_alat(header)
        return self._tags

if __name__ == '__main__':
    import sys
    from phonopy.structure.symmetry import Symmetry
    cell = read_lmto(sys.argv[1])
    symmetry = Symmetry(cell)
    print('# %s' % symmetry.get_international_table())
    print(get_lmto_structure(cell))
示例#54
0
 def _search_symmetry(self):
     self._symmetry = Symmetry(self._supercell,
                               self._symprec,
                               self._is_symmetry)
示例#55
0
class JointDos:
    def __init__(self,
                 mesh,
                 primitive,
                 supercell,
                 fc2,
                 nac_params=None,
                 nac_q_direction=None,
                 sigma=None,
                 cutoff_frequency=None,
                 frequency_step=None,
                 num_frequency_points=None,
                 temperatures=None,
                 frequency_factor_to_THz=VaspToTHz,
                 frequency_scale_factor=1.0,
                 is_nosym=False,
                 symprec=1e-5,
                 filename=None,
                 log_level=False,
                 lapack_zheev_uplo='L'):

        self._grid_point = None
        self._mesh = np.array(mesh, dtype='intc')
        self._primitive = primitive
        self._supercell = supercell
        self._fc2 = fc2
        self._nac_params = nac_params
        self._nac_q_direction = None
        self.set_nac_q_direction(nac_q_direction)
        self._sigma = None
        self.set_sigma(sigma)

        if cutoff_frequency is None:
            self._cutoff_frequency = 0
        else:
            self._cutoff_frequency = cutoff_frequency
        self._frequency_step = frequency_step
        self._num_frequency_points = num_frequency_points
        self._temperatures = temperatures
        self._frequency_factor_to_THz = frequency_factor_to_THz
        self._frequency_scale_factor = frequency_scale_factor
        self._is_nosym = is_nosym
        self._symprec = symprec
        self._filename = filename
        self._log_level = log_level
        self._lapack_zheev_uplo = lapack_zheev_uplo

        self._num_band = self._primitive.get_number_of_atoms() * 3
        self._reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
        self._set_dynamical_matrix()
        self._symmetry = Symmetry(primitive, symprec)

        self._tetrahedron_method = None
        self._phonon_done = None
        self._frequencies = None
        self._eigenvectors = None
            
        self._joint_dos = None
        self._frequency_points = None

    def run(self):
        try:
            import anharmonic._phono3py as phono3c
            self._run_c()
        except ImportError:
            print "Joint density of states in python is not implemented."
            return None, None

    def get_joint_dos(self):
        return self._joint_dos

    def get_frequency_points(self):
        return self._frequency_points

    def get_phonons(self):
        return self._frequencies, self._eigenvectors, self._phonon_done

    def get_primitive(self):
        return self._primitive

    def get_mesh_numbers(self):
        return self._mesh
        
    def set_nac_q_direction(self, nac_q_direction=None):
        if nac_q_direction is not None:
            self._nac_q_direction = np.array(nac_q_direction, dtype='double')

    def set_sigma(self, sigma):
        if sigma is None:
            self._sigma = None
        else:
            self._sigma = float(sigma)

    def set_grid_point(self, grid_point):
        self._grid_point = grid_point
        self._set_triplets()
        num_grid = np.prod(len(self._grid_address))
        num_band = self._num_band
        if self._phonon_done is None:
            self._phonon_done = np.zeros(num_grid, dtype='byte')
            self._frequencies = np.zeros((num_grid, num_band), dtype='double')
            self._eigenvectors = np.zeros((num_grid, num_band, num_band),
                                          dtype='complex128')
            
        self._joint_dos = None
        self._frequency_points = None
        self.set_phonon(np.array([grid_point], dtype='intc'))

    def get_triplets_at_q(self):
        return self._triplets_at_q, self._weights_at_q
        
    def get_grid_address(self):
        return self._grid_address

    def get_bz_map(self):
        return self._bz_map
    
    def _run_c(self, lang='C'):
        if self._sigma is None:
            if lang == 'C':
                self._run_c_with_g()
            else:
                if self._temperatures is not None:
                    print "JDOS with phonon occupation numbers doesn't work",
                    print "in this option."
                self._run_py_tetrahedron_method()
        else:
            self._run_c_with_g()
            # self._run_smearing_method() is an older and direct implementation.
            # This requies less memory space. self._run_c_with_g can be used
            # for smearing method and can share same code with tetrahedron 
            # method. Therefore maintainance cost of code can be reduced by
            # without using self._run_smearing_method().
                
    def _run_c_with_g(self):
        self.set_phonon(self._triplets_at_q.ravel())
        if self._sigma is None:
            f_max = np.max(self._frequencies) * 2
        else:
            f_max = np.max(self._frequencies) * 2 + self._sigma * 4
        f_max *= 1.005
        f_min = 0
        self._set_frequency_points(f_min, f_max)

        num_freq_points = len(self._frequency_points)
        num_mesh = np.prod(self._mesh)

        if self._temperatures is None:
            jdos = np.zeros((num_freq_points, 2), dtype='double')
        else:
            num_temps = len(self._temperatures)
            jdos = np.zeros((num_temps, num_freq_points, 2), dtype='double')
            occ_phonons = []
            for t in self._temperatures:
                freqs = self._frequencies[self._triplets_at_q[:, 1:]]
                occ_phonons.append(np.where(freqs > self._cutoff_frequency,
                                            occupation(freqs, t), 0))
        
        for i, freq_point in enumerate(self._frequency_points):
            g = get_triplets_integration_weights(
                self,
                np.array([freq_point], dtype='double'),
                self._sigma,
                is_collision_matrix=True,
                neighboring_phonons=(i == 0))

            if self._temperatures is None:
                jdos[i, 0] = np.sum(
                    np.tensordot(g[0, :, 0], self._weights_at_q, axes=(0, 0)))
                gx = g[2] - g[0]
                jdos[i, 1] = np.sum(
                    np.tensordot(gx[:, 0], self._weights_at_q, axes=(0, 0)))
            else:
                for j, n in enumerate(occ_phonons):
                    for k, l in list(np.ndindex(g.shape[3:])):
                        jdos[j, i, 0] += np.dot(
                            (n[:, 0, k] + n[:, 1, l] + 1) *
                            g[0, :, 0, k, l], self._weights_at_q)
                        jdos[j, i, 1] += np.dot((n[:, 0, k] - n[:, 1, l]) *
                                                g[1, :, 0, k, l],
                                                self._weights_at_q)

        self._joint_dos = jdos / num_mesh
    
    def _run_py_tetrahedron_method(self):
        thm = TetrahedronMethod(self._reciprocal_lattice, mesh=self._mesh)
        self._vertices = get_tetrahedra_vertices(
            thm.get_tetrahedra(),
            self._mesh,
            self._triplets_at_q,
            self._grid_address,
            self._bz_map)
        self.set_phonon(self._vertices.ravel())
        f_max = np.max(self._frequencies) * 2
        f_max *= 1.005
        f_min = 0
        self._set_frequency_points(f_min, f_max)

        num_freq_points = len(self._frequency_points)
        jdos = np.zeros((num_freq_points, 2), dtype='double')
        for vertices, w in zip(self._vertices, self._weights_at_q):
            for i, j in list(np.ndindex(self._num_band, self._num_band)):
                f1 = self._frequencies[vertices[0], i]
                f2 = self._frequencies[vertices[1], j]
                thm.set_tetrahedra_omegas(f1 + f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 0] += iw * w

                thm.set_tetrahedra_omegas(f1 - f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 1] += iw * w

                thm.set_tetrahedra_omegas(-f1 + f2)
                thm.run(self._frequency_points)
                iw = thm.get_integration_weight()
                jdos[:, 1] += iw * w

        self._joint_dos = jdos / np.prod(self._mesh)

    def _run_smearing_method(self):
        import anharmonic._phono3py as phono3c

        self.set_phonon(self._triplets_at_q.ravel())
        f_max = np.max(self._frequencies) * 2 + self._sigma * 4
        f_min = np.min(self._frequencies) * 2 - self._sigma * 4
        self._set_frequency_points(f_min, f_max)
        jdos = np.zeros((len(self._frequency_points), 2), dtype='double')
        phono3c.joint_dos(jdos,
                          self._frequency_points,
                          self._triplets_at_q,
                          self._weights_at_q,
                          self._frequencies,
                          self._sigma)
        jdos /= np.prod(self._mesh)
        self._joint_dos = jdos
        
    def _set_dynamical_matrix(self):
        self._dm = get_dynamical_matrix(
            self._fc2,
            self._supercell,
            self._primitive,
            nac_params=self._nac_params,
            frequency_scale_factor=self._frequency_scale_factor,
            symprec=self._symprec)
        
    def _set_triplets(self):
        if self._is_nosym:
            if self._log_level:
                print "Triplets at q without considering symmetry"
                sys.stdout.flush()
            
            (self._triplets_at_q,
             self._weights_at_q,
             self._grid_address,
             self._bz_map,
             map_triplets,
             map_q) = get_nosym_triplets_at_q(
                 self._grid_point,
                 self._mesh,
                 self._reciprocal_lattice,
                 with_bz_map=True)
        else:
            (self._triplets_at_q,
             self._weights_at_q,
             self._grid_address,
             self._bz_map,
             map_triplets,
             map_q) = get_triplets_at_q(
                 self._grid_point,
                 self._mesh,
                 self._symmetry.get_pointgroup_operations(),
                 self._reciprocal_lattice)

    def set_phonon(self, grid_points):
        set_phonon_c(self._dm,
                     self._frequencies,
                     self._eigenvectors,
                     self._phonon_done,
                     grid_points,
                     self._grid_address,
                     self._mesh,
                     self._frequency_factor_to_THz,
                     self._nac_q_direction,
                     self._lapack_zheev_uplo)

    def _set_frequency_points(self, f_min, f_max):
        if self._num_frequency_points is None:
            if self._frequency_step is not None:
                self._frequency_points = np.arange(
                    f_min, f_max, self._frequency_step, dtype='double')
            else:
                self._frequency_points = np.array(np.linspace(
                    f_min, f_max, 201), dtype='double')
        else:
            self._frequency_points = np.array(np.linspace(
                f_min, f_max, self._num_frequency_points), dtype='double')
示例#56
0
class PhonopyUnfolding(Phonopy):
    """

    unitcell: before symmetrization
    """
    def __init__(self,
                 unitcell,
                 unitcell_ideal,
                 supercell_matrix,
                 primitive_matrix_ideal,
                 nac_params=None,
                 distance=0.01,
                 factor=VaspToTHz,
                 is_auto_displacements=True,
                 dynamical_matrix_decimals=None,
                 force_constants_decimals=None,
                 star="none",
                 mode="eigenvector",
                 symprec=1e-5,
                 is_symmetry=True,
                 use_lapack_solver=False,
                 log_level=0):
        self._symprec = symprec
        self._distance = distance
        self._factor = factor
        self._is_auto_displacements = is_auto_displacements
        self._is_symmetry = is_symmetry
        self._use_lapack_solver = use_lapack_solver
        self._log_level = log_level

        # Create supercell and primitive cell
        self._unitcell = unitcell
        self._unitcell_ideal = unitcell_ideal
        self._supercell_matrix = supercell_matrix
        self._primitive_matrix = None
        self._primitive_matrix_ideal = primitive_matrix_ideal
        self._supercell = None
        self._primitive = None
        self._build_supercell()
        self._build_primitive_cell()
        self._build_supercell_ideal()
        self._build_primitive_cell_ideal()

        # Set supercell and primitive symmetry
        self._symmetry = None
        self._primitive_symmetry = None
        self._search_symmetry()
        self._search_primitive_symmetry()
        self._search_symmetry_ideal()
        self._search_primitive_symmetry_ideal()

        # set_force_constants or set_forces
        self._force_constants = None
        self._force_constants_decimals = force_constants_decimals

        # set_dynamical_matrix
        self._dynamical_matrix = None
        self._nac_params = nac_params
        self._dynamical_matrix_decimals = dynamical_matrix_decimals

        # set_band_structure
        self._band_structure = None

        # set_mesh
        self._mesh = None

        # set_tetrahedron_method
        self._tetrahedron_method = None

        # set_thermal_properties
        self._thermal_properties = None

        # set_thermal_displacements
        self._thermal_displacements = None

        # set_thermal_displacement_matrices
        self._thermal_displacement_matrices = None

        # set_partial_DOS
        self._pdos = None

        # set_total_DOS
        self._total_dos = None

        # set_modulation
        self._modulation = None

        # set_character_table
        self._irreps = None

        # set_group_velocity
        self._group_velocity = None

        self._star = star
        self._mode = mode

    # Single point
    def run_single_point(self, qpoint, distance):
        SinglePoint(
            qpoint,
            distance,
            dynamical_matrix=self._dynamical_matrix,
            unitcell_ideal=self._unitcell_ideal,
            primitive_matrix_ideal=self._primitive_matrix_ideal,
            factor=self._factor,
            star=self._star,
            mode=self._mode,
            verbose=True)

    # Band structure
    def set_band_structure(self,
                           bands,
                           is_eigenvectors=False,
                           is_band_connection=False):
        if self._dynamical_matrix is None:
            print("Warning: Dynamical matrix has not yet built.")
            self._band_structure = None
            return False

        self._band_structure = BandStructure(
            bands,
            self._dynamical_matrix,
            self._unitcell_ideal,
            self._primitive_matrix_ideal,
            is_eigenvectors=is_eigenvectors,
            is_band_connection=is_band_connection,
            group_velocity=self._group_velocity,
            factor=self._factor,
            star=self._star,
            mode=self._mode,
            verbose=True)
        return True

    # Sampling mesh
    def set_mesh(self,
                 mesh,
                 shift=None,
                 is_time_reversal=True,
                 is_mesh_symmetry=True,
                 is_eigenvectors=False,
                 is_gamma_center=False):
        if self._dynamical_matrix is None:
            print("Warning: Dynamical matrix has not yet built.")
            self._mesh = None
            return False

        # TODO(ikeda): Check how "rotations" works.
        self._mesh = MeshUnfolding(
            self._dynamical_matrix,
            self._unitcell_ideal,
            self._primitive_matrix_ideal,
            mesh,
            shift=shift,
            is_time_reversal=is_time_reversal,
            is_mesh_symmetry=is_mesh_symmetry,
            is_eigenvectors=is_eigenvectors,
            is_gamma_center=is_gamma_center,
            star=self._star,
            group_velocity=self._group_velocity,
            rotations=self._primitive_symmetry.get_pointgroup_operations(),
            factor=self._factor,
            use_lapack_solver=self._use_lapack_solver,
            mode=self._mode)
        return True

    # DOS
    def set_total_DOS(self,
                      sigma=None,
                      freq_min=None,
                      freq_max=None,
                      freq_pitch=None,
                      tetrahedron_method=False):

        if self._mesh is None:
            print("Warning: \'set_mesh\' has to finish correctly "
                  "before DOS calculation.")
            self._total_dos = None
            return False

        total_dos = TotalDosUnfolding(
            self._mesh,
            sigma=sigma,
            tetrahedron_method=tetrahedron_method)
        total_dos.set_draw_area(freq_min, freq_max, freq_pitch)
        total_dos.run()
        self._total_dos = total_dos
        return True

    def _set_dynamical_matrix(self):
        self._dynamical_matrix = None

        if self._supercell is None or self._primitive is None:
            print("Bug: Supercell or primitive is not created.")
            return False
        elif self._force_constants is None:
            print("Warning: Force constants are not prepared.")
            return False
        elif self._primitive.get_masses() is None:
            print("Warning: Atomic masses are not correctly set.")
            return False
        else:
            if self._nac_params is None:
                self._dynamical_matrix = DynamicalMatrix(
                    self._supercell,
                    self._primitive,
                    self._force_constants,
                    decimals=self._dynamical_matrix_decimals,
                    symprec=self._symprec)
            else:
                raise ValueError(
                    'Currently NAC is not available for unfolding.')
            return True

    def _search_symmetry_ideal(self):
        self._symmetry = Symmetry(self._supercell_ideal,
                                  self._symprec,
                                  self._is_symmetry)

    def _search_primitive_symmetry_ideal(self):
        self._primitive_symmetry = Symmetry(self._primitive_ideal,
                                            self._symprec,
                                            self._is_symmetry)

        n0 = len(self._symmetry.get_pointgroup_operations())
        n1 = len(self._primitive_symmetry.get_pointgroup_operations())
        if n0 != n1:
            raise Warning("Point group symmetries of supercell and primitive"
                          "cell are different.")

    def _build_supercell_ideal(self):
        self._supercell_ideal = get_supercell(
            self._unitcell_ideal,
            self._supercell_matrix,
            self._symprec)

    def _build_primitive_cell_ideal(self):
        """
        primitive_matrix:
          Relative axes of primitive cell to the input unit cell.
          Relative axes to the supercell is calculated by:
             supercell_matrix^-1 * primitive_matrix
          Therefore primitive cell lattice is finally calculated by:
             (supercell_lattice * (supercell_matrix)^-1 * primitive_matrix)^T
        """

        inv_supercell_matrix = np.linalg.inv(self._supercell_matrix)
        if self._primitive_matrix_ideal is None:
            trans_mat = inv_supercell_matrix
        else:
            trans_mat = np.dot(inv_supercell_matrix, self._primitive_matrix_ideal)
        self._primitive_ideal = get_primitive(
            self._supercell_ideal, trans_mat, self._symprec)
        num_satom = self._supercell_ideal.get_number_of_atoms()
        num_patom = self._primitive_ideal.get_number_of_atoms()
        if abs(num_satom * np.linalg.det(trans_mat) - num_patom) < 0.1:
            return True
        else:
            return False

    def average_masses(self):

        masses = self._unitcell.get_masses()
        masses_average = calculate_average_masses(
            masses, Symmetry(self._unitcell_ideal))
        self._unitcell.set_masses(masses_average)

        self._build_supercell()
        self._build_primitive_cell()

        self._search_symmetry()
        self._search_primitive_symmetry()

    def average_force_constants(self):
        fc_symmetrizer_spg = FCSymmetrizerSPG(
            force_constants=self._force_constants,
            atoms=self._unitcell,
            atoms_ideal=self._unitcell_ideal,
            supercell_matrix=self._supercell_matrix,
        )
        fc_symmetrizer_spg.average_force_constants_spg()
        fc_symmetrizer_spg.write_force_constants_symmetrized()
        fc_average = fc_symmetrizer_spg.get_force_constants_symmetrized()
        self.set_force_constants(fc_average)  # Dynamical matrices are also prepared inside.
示例#57
0
        magmom = []
        for numxmag in text.split():
            if '*' in numxmag:
                num, mag = numxmag.split('*')
                magmom += [float(mag)] * int(num)
            else:
                magmom.append(float(numxmag))
        return magmom
    
    def parse_incar(filename):
        for line in open(filename):
            for conf in line.split(';'):
                if 'MAGMOM' in conf:
                    return get_magmom(conf.split('=')[1])
    
    cell = read_vasp("POSCAR")
    symmetry = Symmetry(cell, symprec=1e-3)
    map_nonspin = symmetry.get_map_atoms()
    print "Number of operations w/o spin", len(symmetry.get_symmetry_operations()['rotations'])
    magmoms = parse_incar("INCAR")
    cell.set_magnetic_moments(magmoms)
    symmetry = Symmetry(cell, symprec=1e-3)
    print "Number of operations w spin", len(symmetry.get_symmetry_operations()['rotations'])
    map_withspin = symmetry.get_map_atoms()
    if ((map_nonspin - map_withspin) == 0).all():
        print True
    else:
        print False
        print map_nonspin
        print map_withspin
示例#58
0
文件: siesta.py 项目: nfh/phonopy
            elif tag == "atomiccoordinatesandatomicspecies":
                lines = block.split('\n')[:-1]
                self._tags["atomiccoordinates"] = [ [float(x)  for x in atom.split()[:3]] for atom in lines ]
                self._tags["atomicspecies"] = [ int(atom.split()[3]) for atom in lines]
       
        #check if the block are present
        self.check_present("atomicspecies")
        self.check_present("atomiccoordinates")
        self.check_present("latticevectors")
        self.check_present("chemicalspecieslabel")
            
        #translate the atomicspecies to atomic numbers
        self._tags["atomicnumbers"] = [self._tags["atomicnumbers"][atype] for atype in self._tags["atomicspecies"]]
    
    def check_present(self,tag):
        if not self._tags[tag]:
            print "%s not present"%tag
            exit()
 
    def __str__():
        return self._tags

        
if __name__ == '__main__':
    import sys
    from phonopy.structure.symmetry import Symmetry
    cell,atypes = read_siesta(sys.argv[1])
    symmetry = Symmetry(cell)
    print "#", symmetry.get_international_table()
    print get_siesta_structure(cell,atypes)
示例#59
0
            shortest_indices = [i for i, d in enumerate(distances - min_dist)
                                if abs(d) < self._tolerance]
            self._shortest_qpoints.append(
                np.dot(search_space[shortest_indices] + q, self._tmat.T))

    def get_shortest_qpoints(self):
        return self._shortest_qpoints

if __name__ == '__main__':
    from phonopy.interface.vasp import read_vasp
    from phonopy.structure.symmetry import Symmetry, get_lattice_vector_equivalence
    from phonopy.structure.spglib import get_ir_reciprocal_mesh, relocate_BZ_grid_address
    import sys

    cell = read_vasp(sys.argv[1])
    symmetry = Symmetry(cell)
    mesh = [4, 4, 4]
    is_shift = np.array([0, 0, 0], dtype='intc')
    mapping_table, grid_address = get_ir_reciprocal_mesh(
        mesh,
        cell,
        is_shift=is_shift)
    ir_grid_points = np.unique(mapping_table)
    primitive_vectors = np.linalg.inv(cell.get_cell())
    bz_grid_address, bz_map = relocate_BZ_grid_address(
        grid_address,
        mesh,
        np.linalg.inv(cell.get_cell()),
        is_shift=is_shift)

    bz_points = np.extract(bz_map > -1, bz_map)