コード例 #1
0
    def run(self, atom_pairs):
        s2p = self._primitive.get_supercell_to_primitive_map()
        p2p = self._primitive.get_primitive_to_primitive_map()
        dists = np.zeros((len(self._temperatures), len(atom_pairs)),
                         dtype=float)
        for i, (atom1, atom2) in enumerate(atom_pairs):
            patom1 = p2p[s2p[atom1]]
            patom2 = p2p[s2p[atom2]]
            delta_r = get_equivalent_smallest_vectors(
                atom2, atom1, self._supercell, self._primitive.get_cell(),
                self._symprec)[0]

            self._project_eigenvectors(delta_r, self._primitive.get_cell())

            for freqs, vecs, q in zip(self._frequencies, self._p_eigenvectors,
                                      self._qpoints):
                c_cross = 1.0 / np.sqrt(
                    self._masses[patom1] * self._masses[patom2])
                c1 = 1.0 / self._masses[patom1]
                c2 = 1.0 / self._masses[patom2]

                for f, v in zip(freqs, vecs.T):
                    cross_term = self._get_cross(v, delta_r, q, patom1, patom2)
                    v2 = abs(v)**2
                    if f > self._cutoff_frequency:
                        for j, t in enumerate(self._temperatures):
                            dists[j, i] += self.get_Q2(f, t) * (
                                v2[patom1] * c1 + cross_term * c_cross +
                                v2[patom2] * c2)

        self._atom_pairs = atom_pairs
        self._distances = dists / len(self._frequencies)
コード例 #2
0
ファイル: fc3.py プロジェクト: chrinide/phono3py
def cutoff_fc3_by_zero(fc3, supercell, cutoff_distance, symprec=1e-5):
    num_atom = supercell.get_number_of_atoms()
    lattice = supercell.get_cell().T
    min_distances = np.zeros((num_atom, num_atom), dtype='double')
    for i in range(num_atom):  # run in supercell
        for j in range(num_atom):  # run in primitive
            min_distances[i, j] = np.linalg.norm(
                np.dot(
                    lattice,
                    get_equivalent_smallest_vectors(i, j, supercell, lattice.T,
                                                    symprec)[0]))

    for i, j, k in np.ndindex(num_atom, num_atom, num_atom):
        for pair in ((i, j), (j, k), (k, i)):
            if min_distances[pair] > cutoff_distance:
                fc3[i, j, k] = 0
                break
コード例 #3
0
ファイル: displacement_fc3.py プロジェクト: chrinide/phono3py
def get_third_order_displacements(cell,
                                  symmetry,
                                  is_plusminus='auto',
                                  is_diagonal=False):
    # Atoms 1, 2, and 3 are defined as follows:
    #
    # Atom 1: The first displaced atom. Third order force constant
    #         between Atoms 1, 2, and 3 is calculated.
    # Atom 2: The second displaced atom. Second order force constant
    #         between Atoms 2 and 3 is calculated.
    # Atom 3: Force is mesuared on this atom.

    positions = cell.get_scaled_positions()
    lattice = cell.get_cell().T

    # Least displacements for third order force constants in yaml file
    #
    # Data structure
    # [{'number': atom1,
    #   'displacement': [0.00000, 0.007071, 0.007071],
    #   'second_atoms': [ {'number': atom2,
    #                      'displacements': [[0.007071, 0.000000, 0.007071],
    #                                        [-0.007071, 0.000000, -0.007071]
    #                                        ,...]},
    #                     {'number': ... } ] },
    #  {'number': atom1, ... } ]

    # Least displacements of first atoms (Atom 1) are searched by
    # using respective site symmetries of the original crystal.
    disps_first = get_least_displacements(symmetry,
                                          is_plusminus=is_plusminus,
                                          is_diagonal=False)

    symprec = symmetry.get_symmetry_tolerance()

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

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

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

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

            min_distance = np.linalg.norm(
                np.dot(lattice, get_equivalent_smallest_vectors(
                    atom1,
                    atom2,
                    cell,
                    lattice.T,
                    symprec)[0]))
            dds_atom2['distance'] = min_distance
            dds_atom1['second_atoms'].append(dds_atom2)
        dds.append(dds_atom1)
    
    return dds