Beispiel #1
0
def get_renormalized_force_constants(renormalized_frequencies, eigenvectors, structure, fc_supercell, symmetrize=False):

    phonon = get_phonon(structure, setup_forces=False, custom_supercell=fc_supercell)

    primitive = phonon.get_primitive()
    supercell = phonon.get_supercell()

    dynmat2fc = DynmatToForceConstants(primitive, supercell)

    size = structure.get_number_of_dimensions() * structure.get_number_of_primitive_atoms()
    eigenvectors = np.array([eigenvector.reshape(size, size, order='C').T for eigenvector in eigenvectors ])
    renormalized_frequencies = np.array(renormalized_frequencies)

    try:
        dynmat2fc.set_dynamical_matrices(renormalized_frequencies / VaspToTHz, eigenvectors)

    except TypeError:
        dynmat2fc.create_dynamical_matrices(frequencies=renormalized_frequencies / VaspToTHz,
                                            eigenvalues=None,
                                            eigenvectors=eigenvectors)

    dynmat2fc.run()

    force_constants = ForceConstants(dynmat2fc.get_force_constants(), supercell=fc_supercell)

    # Symmetrize force constants using crystal symmetry
    if symmetrize:
        print('Symmetrizing force constants')
        set_tensor_symmetry_PJ(force_constants.get_array(),
                               phonon.supercell.get_cell(),
                               phonon.supercell.get_scaled_positions(),
                               phonon.symmetry)

    return force_constants
Beispiel #2
0
    def run_correlation_matrix(self, T):
        """Calculate displacement-displacement correlation matrix."""
        qpoints, eigvals, eigvecs = self._collect_eigensolutions()
        d2f = DynmatToForceConstants(self._dynmat.primitive,
                                     self._dynmat.supercell)
        masses = self._dynmat.supercell.masses
        d2f.commensurate_points = qpoints
        freqs = np.sqrt(np.abs(eigvals)) * self._factor
        conditions = freqs > self._cutoff_frequency
        a = self._get_sigma(eigvals, T)
        a2 = a**2
        _a = np.where(conditions, a, 1)
        a2_inv = np.where(conditions, 1 / _a**2, 0)

        d2f.create_dynamical_matrices(a2_inv, eigvecs)
        d2f.run()
        self._uu_inv = np.array(d2f.force_constants, dtype="double", order="C")

        d2f.create_dynamical_matrices(a2, eigvecs)
        d2f.run()
        matrix = d2f.force_constants
        for i, m_i in enumerate(masses):
            for j, m_j in enumerate(masses):
                matrix[i, j] /= m_i * m_j
        self._uu = np.array(matrix, dtype="double", order="C")
Beispiel #3
0
 def run_d2f(self):
     qpoints, eigvals, eigvecs = self._collect_eigensolutions()
     d2f = DynmatToForceConstants(self._dynmat.primitive,
                                  self._dynmat.supercell)
     d2f.commensurate_points = qpoints
     d2f.create_dynamical_matrices(eigvals, eigvecs)
     d2f.run()
     self._force_constants = d2f.force_constants
Beispiel #4
0
def test_with_eigenvalues(ph_nacl, ph_nacl_nonac):
    for ph in (ph_nacl_nonac, ph_nacl):
        d2f = DynmatToForceConstants(ph.primitive, ph.supercell)
        ph.run_qpoints(d2f.commensurate_points,
                       with_eigenvectors=True,
                       with_dynamical_matrices=True)
        ph_dict = ph.get_qpoints_dict()
        eigenvalues = ((ph_dict['frequencies'] / VaspToTHz) ** 2 *
                       np.sign(ph_dict['frequencies']))
        d2f.create_dynamical_matrices(eigenvalues=eigenvalues,
                                      eigenvectors=ph_dict['eigenvectors'])
        d2f.run()
        np.testing.assert_allclose(ph.force_constants, d2f.force_constants,
                                   atol=1e-5)
Beispiel #5
0
def test_with_eigenvalues(ph_nacl, ph_nacl_nonac):
    """Test transformation from eigensolutions to dynamical matrix."""
    for ph in (ph_nacl_nonac, ph_nacl):
        d2f = DynmatToForceConstants(ph.primitive, ph.supercell)
        ph.run_qpoints(
            d2f.commensurate_points,
            with_eigenvectors=True,
            with_dynamical_matrices=True,
        )
        ph_dict = ph.get_qpoints_dict()
        eigenvalues = (ph_dict["frequencies"] / VaspToTHz)**2 * np.sign(
            ph_dict["frequencies"])
        d2f.create_dynamical_matrices(eigenvalues=eigenvalues,
                                      eigenvectors=ph_dict["eigenvectors"])
        d2f.run()
        np.testing.assert_allclose(ph.force_constants,
                                   d2f.force_constants,
                                   atol=1e-5)
Beispiel #6
0
class DispCorrMatrixMesh(object):
    """Calculate upsilon and psi matrix

    This calculation is similar to the transformation from
    dynamical matrices to force constants. Instead of creating
    dynamcial matrices from eigenvalues and eigenvectors,
    1/a**2 or a**2 and eigenvectors are used, where a is mode length.

    psi_matrix : ndarray
        Displacement-displacement correlation matrix at temperature.
        Physical unit is [Angstrom^2].
        shape=(3 * num_satom, 3 * num_satom), dtype='double', order='C'
    upsilon_matrix : ndarray
        Inverse displacement-displacement correlation matrix at temperature.
        Physical unit is [1/Angstrom^2].
        shape=(3 * num_satom, 3 * num_satom), dtype='double', order='C'
    commensurate_points : ndarray
        Commensurate q-points of transformation matrix from primitive cell
        to supercell.
        shape=(det(transformation_matrix), 3), dtype='double', order='C'.

    """
    def __init__(self, primitive, supercell, cutoff_frequency=1e-5):
        self._d2f = DynmatToForceConstants(primitive,
                                           supercell,
                                           is_full_fc=True)
        self._masses = supercell.masses
        self._cutoff_frequency = cutoff_frequency

        self._psi_matrix = None
        self._upsilon_matrix = None

    @property
    def commensurate_points(self):
        return self._d2f.commensurate_points

    def run(self, frequencies, eigenvectors, T):
        """

        Parameters
        ----------
        frequencies : ndarray
            Supercell phonon frequencies in THz (without 2pi).
            shape=(grid_point, band), dtype='double', order='C'
        eigenvectors : ndarray
            Supercell phonon eigenvectors.
            shape=(grid_point, band, band), dtype='double', order='C'

        """

        condition = frequencies > self._cutoff_frequency
        _freqs = np.where(condition, frequencies, 1)
        _a = mode_length(_freqs, T)
        a2 = np.where(condition, _a**2, 0)
        a2_inv = np.where(condition, 1 / _a**2, 0)
        N = len(self._masses)
        shape = (N * 3, N * 3)

        self._d2f.create_dynamical_matrices(a2_inv, eigenvectors)
        self._d2f.run()
        matrix = self._d2f.force_constants
        matrix = np.transpose(matrix, axes=[0, 2, 1, 3]).reshape(shape)
        self._upsilon_matrix = np.array(matrix, dtype='double', order='C')

        self._d2f.create_dynamical_matrices(a2, eigenvectors)
        self._d2f.run()
        matrix = self._d2f.force_constants
        for i, m_i in enumerate(self._masses):
            for j, m_j in enumerate(self._masses):
                matrix[i, j] /= m_i * m_j
        matrix = np.transpose(matrix, axes=[0, 2, 1, 3]).reshape(shape)
        self._psi_matrix = np.array(matrix, dtype='double', order='C')

    @property
    def upsilon_matrix(self):
        return self._upsilon_matrix

    @property
    def psi_matrix(self):
        return self._psi_matrix