Пример #1
0
    def make_Gonze_nac_dataset(self):
        """Prepare Gonze-Lee force constants.

        Dipole-dipole interaction contribution is subtracted from
        supercell force constants.

        """
        try:
            import phonopy._phonopy as phonoc  # noqa F401

            self._run_c_recip_dipole_dipole_q0()
        except ImportError:
            print("Python version of dipole-dipole calculation is not well "
                  "implemented.")
            sys.exit(1)

        fc_shape = self._force_constants.shape
        d2f = DynmatToForceConstants(self._pcell,
                                     self._scell,
                                     is_full_fc=(fc_shape[0] == fc_shape[1]))
        dynmat = []
        num_q = len(d2f.commensurate_points)
        for i, q_red in enumerate(d2f.commensurate_points):
            if self._log_level > 2:
                print("%d/%d %s" % (i + 1, num_q, q_red))
            self._run(q_red)
            dm_dd = self._get_Gonze_dipole_dipole(q_red, None)
            self._dynamical_matrix -= dm_dd
            dynmat.append(self._dynamical_matrix)
        d2f.dynamical_matrices = dynmat
        d2f.run()

        self._Gonze_force_constants = d2f.force_constants
        self._Gonze_count = 0
Пример #2
0
    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
Пример #3
0
def test_with_dynamical_matrices(ph_nacl, ph_nacl_nonac):
    for ph in (ph_nacl, ph_nacl_nonac):
        d2f = DynmatToForceConstants(ph.primitive, ph.supercell)
        ph.run_qpoints(d2f.commensurate_points,
                       with_dynamical_matrices=True)
        ph_dict = ph.get_qpoints_dict()
        d2f.dynamical_matrices = ph_dict['dynamical_matrices']
        d2f.run()
        np.testing.assert_allclose(ph.force_constants, d2f.force_constants,
                                   atol=1e-5)
Пример #4
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
Пример #5
0
def get_commensurate_points(structure, fc_supercell):

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

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

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    com_points = dynmat2fc.get_commensurate_points()

    return com_points
Пример #6
0
def get_commensurate_points(structure, fc_supercell):

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

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

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    com_points = dynmat2fc.get_commensurate_points()

    return com_points
Пример #7
0
def get_commensurate_points_info(structure):

    phonon = get_phonon(structure)

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

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    com_points = dynmat2fc.get_commensurate_points()

    phonon.set_qpoints_phonon(com_points, is_eigenvectors=True)

    return com_points, dynmat2fc, phonon
Пример #8
0
def phonopy_commensurate_shifts_inline(**kwargs):
    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy import Phonopy
    from phonopy.harmonic.dynmat_to_fc import get_commensurate_points, DynmatToForceConstants

    structure = kwargs.pop('structure')
    phonopy_input = kwargs.pop('phonopy_input').get_dict()
    force_constants = kwargs.pop('force_constants').get_array('force_constants')
    r_force_constants = kwargs.pop('r_force_constants').get_array('force_constants')


    # Generate phonopy phonon object
    bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                        positions=[site.position for site in structure.sites],
                        cell=structure.cell)

    phonon = Phonopy(bulk,
                     phonopy_input['supercell'],
                     primitive_matrix=phonopy_input['primitive'],
                     distance=phonopy_input['distance'])

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


    phonon.set_force_constants(force_constants)

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    com_points = dynmat2fc.get_commensurate_points()

    phonon.set_qpoints_phonon(com_points,
                              is_eigenvectors=True)
    frequencies_h = phonon.get_qpoints_phonon()[0]


    phonon.set_force_constants(r_force_constants)

    phonon.set_qpoints_phonon(com_points,
                              is_eigenvectors=True)
    frequencies_r = phonon.get_qpoints_phonon()[0]

    shifts = frequencies_r - frequencies_h

    # Stores DOS data in DB as a workflow result
    commensurate = ArrayData()
    commensurate.set_array('qpoints', com_points)
    commensurate.set_array('shifts', shifts)

    return {'commensurate': commensurate}
Пример #9
0
def test_with_dynamical_matrices(ph_nacl, ph_nacl_nonac, is_nac, lang):
    """Test transformation from dynamical matrix to force constants."""
    if is_nac:
        ph = ph_nacl
    else:
        ph = ph_nacl_nonac

    d2f = DynmatToForceConstants(ph.primitive, ph.supercell)
    ph.run_qpoints(d2f.commensurate_points, with_dynamical_matrices=True)
    ph_dict = ph.get_qpoints_dict()
    d2f.dynamical_matrices = ph_dict["dynamical_matrices"]
    d2f.run(lang=lang)
    np.testing.assert_allclose(ph.force_constants,
                               d2f.force_constants,
                               atol=1e-5)
Пример #10
0
 def _run_Gonze_force_constants(self):
     fc_shape = self._force_constants.shape
     d2f = DynmatToForceConstants(self._pcell,
                                  self._scell,
                                  is_full_fc=(fc_shape[0] == fc_shape[1]))
     dynmat = []
     num_q = len(d2f.commensurate_points)
     for i, q_red in enumerate(d2f.commensurate_points):
         if self._log_level > 2:
             print("%d/%d %s" % (i + 1, num_q, q_red))
         self._run(q_red)
         dm_dd = self._get_Gonze_dipole_dipole(q_red, None)
         self._dynamical_matrix -= dm_dd
         dynmat.append(self._dynamical_matrix)
     d2f.dynamical_matrices = dynmat
     d2f.run()
     self._Gonze_force_constants = d2f.force_constants
Пример #11
0
def get_commensurate(structure, ph_settings):
    from phonopy import Phonopy
    from phonopy.harmonic.dynmat_to_fc import DynmatToForceConstants
    from aiida_phonopy.workchains.phonon import phonopy_bulk_from_structure

    phonon = Phonopy(phonopy_bulk_from_structure(structure),
                     ph_settings.dict.supercell,
                     primitive_matrix=ph_settings.dict.primitive,
                     symprec=ph_settings.dict.symmetry_precision)

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

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    commensurate = dynmat2fc.get_commensurate_points()

    return dynmat2fc, commensurate
Пример #12
0
def get_force_constants(phonon_origin, gruneisen, commensurate, volumes):
    from phonopy.harmonic.dynmat_to_fc import DynmatToForceConstants
    from phonopy.units import VaspToTHz

    from copy import deepcopy
    phonon = deepcopy(phonon_origin)

    phonon.set_qpoints_phonon(commensurate,
                              is_eigenvectors=True)
    frequencies, eigenvectors = phonon.get_qpoints_phonon()

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

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    volume_ref = phonon.get_unitcell().get_volume()

    force_constants_list = []
    for volume in volumes:
        renormalized_frequencies = []
        for freq, g in zip(frequencies, gruneisen):
            renormalized_frequencies.append(freq + (freq * (np.exp(-g*np.log(volume/volume_ref))-1)))
        renormalized_frequencies = np.array(renormalized_frequencies)

        # Fixing Gamma point data
        renormalized_frequencies[0][0:3] = [0.0, 0.0, 0.0]

        dynmat2fc.set_dynamical_matrices(renormalized_frequencies / VaspToTHz, eigenvectors)
        dynmat2fc.run()
        force_constants_list.append(np.array(dynmat2fc.get_force_constants()))

    return force_constants_list
Пример #13
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
Пример #14
0
 def _set_Gonze_force_constants(self):
     d2f = DynmatToForceConstants(self._pcell,
                                  self._scell,
                                  symprec=self._symprec)
     self._force_constants = self._bare_force_constants
     dynmat = []
     num_q = len(d2f.get_commensurate_points())
     for i, q_red in enumerate(d2f.get_commensurate_points()):
         print("%d/%d %s" % (i + 1, num_q, q_red))
         self._set_dynamical_matrix(q_red)
         dm_dd = self._get_Gonze_dipole_dipole(q_red, None)
         self._dynamical_matrix -= dm_dd
         dynmat.append(self._dynamical_matrix)
     d2f.set_dynamical_matrices(dynmat=dynmat)
     d2f.run()
     self._Gonze_force_constants = d2f.get_force_constants()
Пример #15
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)

    dynmat2fc.set_dynamical_matrices(renormalized_frequencies / VaspToTHz, 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
Пример #16
0
    def run_d2f(self):
        N = len(self._comm_points)
        if self._ij:
            eigvals = np.vstack(
                (self._eigvals_ii, self._eigvals_ij, self._eigvals_ij))
            eigvecs = np.vstack(
                (self._eigvecs_ii, self._eigvecs_ij, self._eigvecs_ij))
            eigvecs[-len(self._ij):] = eigvecs[-len(self._ij):].conj()
            qpoints = self._comm_points[self._ii + self._ij * 2] / float(N)
            qpoints[-len(self._ij):] = -qpoints[-len(self._ij):]
        else:
            eigvals = self._eigvals_ii
            eigvecs = self._eigvecs_ii
            qpoints = self._comm_points[self._ii] / float(N)

        d2f = DynmatToForceConstants(self._dynmat.primitive,
                                     self._dynmat.supercell,
                                     eigenvalues=eigvals,
                                     eigenvectors=eigvecs,
                                     commensurate_points=qpoints)
        d2f.run()
        self._force_constants = d2f.force_constants
Пример #17
0
 def _set_Gonze_force_constants(self):
     d2f = DynmatToForceConstants(self._pcell,
                                  self._scell,
                                  symprec=self._symprec)
     dynmat = []
     num_q = len(d2f.get_commensurate_points())
     for i, q_red in enumerate(d2f.get_commensurate_points()):
         if self._log_level > 1:
             print("%d/%d %s" % (i + 1, num_q, q_red))
         self._set_dynamical_matrix(q_red)
         dm_dd = self._get_Gonze_dipole_dipole(q_red, None)
         self._dynamical_matrix -= dm_dd
         dynmat.append(self._dynamical_matrix)
     d2f.set_dynamical_matrices(dynmat=dynmat)
     d2f.run()
     self._Gonze_force_constants = d2f.get_force_constants()
Пример #18
0
def get_commensurate_points(structure, phonopy_input):

    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy.harmonic.dynmat_to_fc import DynmatToForceConstants
    from phonopy import Phonopy

    # Generate phonopy phonon object
    bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                        positions=[site.position for site in structure.sites],
                        cell=structure.cell)

    phonon = Phonopy(bulk,
                     phonopy_input['supercell'],
                     primitive_matrix=phonopy_input['primitive'],
                     distance=phonopy_input['distance'],
                     symprec=phonopy_input['symmetry_precision'])

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

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    com_points = dynmat2fc.get_commensurate_points()

    return com_points
Пример #19
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)
Пример #20
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)
Пример #21
0
def phonopy_merge(**kwargs):
    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy import Phonopy
    from phonopy.units import VaspToTHz
    from phonopy.harmonic.dynmat_to_fc import get_commensurate_points, DynmatToForceConstants

    structure = kwargs.pop('structure')
    phonopy_input = kwargs.pop('phonopy_input').get_dict()

    harmonic = kwargs.pop('harmonic')
    renormalized = kwargs.pop('renormalized')

    eigenvectors = harmonic.get_array('eigenvectors')
    frequencies = harmonic.get_array('frequencies')
    shifts = renormalized.get_array('shifts')


    # Generate phonopy phonon object
    bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                        positions=[site.position for site in structure.sites],
                        cell=structure.cell)

    phonon = Phonopy(bulk,
                     phonopy_input['supercell'],
                     primitive_matrix=phonopy_input['primitive'],
                     distance=phonopy_input['distance'])

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



    total_frequencies = frequencies + shifts

    dynmat2fc = DynmatToForceConstants(primitive, supercell)
    dynmat2fc.set_dynamical_matrices(total_frequencies / VaspToTHz, eigenvectors)
    dynmat2fc.run()

    total_force_constants = dynmat2fc.get_force_constants()

    # Stores DOS data in DB as a workflow result
    total_data = ArrayData()
    total_data.set_array('force_constants', total_force_constants)

    return {'final_results': total_data}



    # Start script here

    # Workflow phonon (at given volume)
    wf = load_workflow(431)
    parameters = wf.get_parameters()
    results = wf.get_results()

    inline_params = {'structure': results['final_structure'],
                     'phonopy_input': parameters['phonopy_input'],
                     'force_constants': results['force_constants']}

    harmonic = phonopy_commensurate_inline(**inline_params)



    # At reference volume (at T = 0)
    wf = load_workflow(432)
    parameters = wf.get_parameters()
    results_r = wf.get_results()
    results_h = wf.get_results()


    inline_params = {'structure': results_h['final_structure'],
                     'phonopy_input': parameters['phonopy_input'],
                     'force_constants': results_h['force_constants'],
                     'r_force_constants': results_r['r_force_constants']}


    renormalized = phonopy_commensurate_shifts_inline(**inline_params)





    inline_params = {'structure': results_h['final_structure'],
                     'phonopy_input': parameters['phonopy_input'],
                     'harmonic': harmonic,
                     'renormalized': renormalized}

    total = phonopy_merge(**inline_params)

    print total

    inline_params = {'structure': results_h['final_structure'],
                     'phonopy_input': parameters['phonopy_input'],
                     'force_constants': total['force_constants']}

    results = phonopy_calculation_inline(**inline_params)[1]

    band = results['band_structure']


    # Phonon Band structure plot
    plot_data(results['band_structure'])
Пример #22
0
    band = []
    for i in range(51):
        band.append(
            np.array(q_start) + (np.array(q_end) - np.array(q_start)) / 50 * i)
    bands.append(band)


bulk = read_vasp("POSCAR")
phonon = Phonopy(bulk, [[2, 0, 0], [0, 2, 0], [0, 0, 2]],
                 primitive_matrix=[[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5,
                                                                  0]],
                 is_auto_displacements=False)

primitive = phonon.get_primitive()
supercell = phonon.get_supercell()
dynmat2fc = DynmatToForceConstants(primitive, supercell)
com_points = dynmat2fc.get_commensurate_points()

print "Commensurate points"
for i, q in enumerate(com_points):
    print i + 1, q

force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()
phonon.set_qpoints_phonon(com_points, is_eigenvectors=True)
frequencies, eigenvectors = phonon.get_qpoints_phonon()
dynmat2fc.set_dynamical_matrices(frequencies / VaspToTHz, eigenvectors)
dynmat2fc.run()
fc = dynmat2fc.get_force_constants()
Пример #23
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
Пример #24
0
                    (np.array(q_end) - np.array(q_start)) / 50 * i)
    bands.append(band)

bulk = read_vasp("POSCAR")
phonon = Phonopy(bulk,
                 [[2, 0, 0],
                  [0, 2, 0],
                  [0, 0, 2]],
                 primitive_matrix=[[0, 0.5, 0.5],
                                   [0.5, 0, 0.5],
                                   [0.5, 0.5, 0]],
                 is_auto_displacements=False)

primitive = phonon.get_primitive()
supercell = phonon.get_supercell()
dynmat2fc = DynmatToForceConstants(primitive, supercell)
com_points = dynmat2fc.get_commensurate_points()

print "Commensurate points"
for i, q in enumerate(com_points):
    print i + 1, q

force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()
phonon.set_qpoints_phonon(com_points,
                          is_eigenvectors=True)
frequencies, eigenvectors = phonon.get_qpoints_phonon()
dynmat2fc.set_dynamical_matrices(frequencies / VaspToTHz, eigenvectors)
dynmat2fc.run()
fc = dynmat2fc.get_force_constants()
Пример #25
0
def BuildForceConstants(lattice_vectors, atom_types, atom_pos, q_pts, freqs, eigs, sc_dim, freq_units = 'thz', atom_mass = None, file_path = r"FORCE_CONSTANTS"):
    """
    Use the Phonopy API to take a set of frequencies and eigenvectors, construct a dynamical matrix, transform to a set of force constants, and write out a Phonopy FORCE_CONSTANTS file.

    Args:
        lattice_vectors -- 3x3 matrix containing the lattice vectors
        atom_types -- list of atomic symbols
        atom_pos -- list of atomic positions ** in fractional coordinates **
        q_pts -- list of q-point coordinates
        freqs -- n_q sets of Frequencies
        eigs -- n_q sets of eigenvectors
        sc_dim -- (equivalent) supercell dimension for preparing force constants
        freq_units -- units of freqs ('thz' or 'inv_cm' -- default: 'thz')
        atom_mass -- (optional) list of atomic masses (default: taken from Phonopy internal database)
        file_path -- path to FORCE_CONSTANTS file to write (default: FORCE_CONSTANTS)
    """

    # Check input.

    _CheckStructure(lattice_vectors, atom_types, atom_pos, atom_mass)

    for param in q_pts, freqs, eigs, sc_dim:
        assert param is not None

    dim_1, dim_2 = np.shape(q_pts)

    assert dim_1 > 0 and dim_2 == 3

    n_at = len(atom_types)

    n_q = dim_1
    n_b = 3 * n_at

    dim_1, dim_2 = np.shape(freqs)

    assert dim_1 == n_q and dim_2 == n_b

    dim_1, dim_2, dim_3, dim_4 = np.shape(eigs)

    assert dim_1 == n_q and dim_2 == n_b and dim_3 == n_at and dim_4 == 3

    dim_1, = np.shape(sc_dim)

    assert dim_1 == 3

    # Obtain a frequency conversion factor to "VASP units".

    freq_conv_factor = None

    if freq_units == 'thz':
        freq_conv_factor = VaspToTHz
    elif freq_units == 'inv_cm':
        freq_conv_factor = VaspToCm

    if freq_conv_factor is None:
        raise Exception("Error: Unknown freq_units '{0}'.".format(freq_units))

    # Create a Phonopy-format structure.

    structure = PhonopyAtoms(
        symbols = atom_types, masses = atom_mass, scaled_positions = atom_pos, cell = lattice_vectors
        )

    # Convert supercell expansion to a supercell matrix.

    dim_1, dim_2, dim_3 = sc_dim

    if dim_1 != dim_2 != dim_2 != 1:
        warnings.warn("The dynamical matrix -> force constants transform has only been tested at the Gamma point; please report issues to the developer.", RuntimeWarning)

    sc_matrix = [[dim_1, 0, 0], [0, dim_2, 0], [0, 0, dim_3]]

    # Use the main Phonopy object to obtain the primitive cell and supercell.

    calculator = Phonopy(structure, sc_matrix)

    primitive = calculator.get_primitive();
    supercell = calculator.get_supercell();

    # Use the DynmatToForceConstants object to convert frequencies/eigenvectors -> dynamical matrices -> force constants.

    dynmat_to_fc = DynmatToForceConstants(primitive, supercell)

    commensurate_points = dynmat_to_fc.get_commensurate_points()

    # If an input code does not use crystal symmetry or outputs data at all q-points in a sampling mesh, data may be provided for more q-points than there are commensurate points.
    # However, for most codes this would be an odd situation -> issue a warning.

    if len(commensurate_points) != n_q:
        warnings.warn("The number of entries in the q_pts list does not equal the number of commensurate points expected for the supplied supercell matrix.", RuntimeWarning)

    # Map commensurate points in Phonopy setup to q-points in input data.

    map_indices = []

    for qx_1, qy_1, qz_1 in commensurate_points:
        map_index = None

        for i, (qx_2, qy_2, qz_2) in enumerate(q_pts):
            if math.fabs(qx_2 - qx_1) < _SymPrec and math.fabs(qy_2 - qy_1) < _SymPrec and math.fabs(qz_2 - qz_1) < _SymPrec:
                map_index = i
                break

        if map_index is None:
            raise Exception("Error: Expected q = ({0: >6.3f}, {1: >6.3f}, {2: >6.3f}) in the q_pts list (this may be a bug; please report to the developer).".format(qx_1, qy_1, qz_1))

        # Sanity check.

        assert map_index not in map_indices

        map_indices.append(map_index)

    # Arrange the frequencies and eigenvectors to the layout required by Phonopy.

    freq_sets, eig_sets = [], []

    for index in map_indices:
        freq_sets.append(
            [freq / freq_conv_factor for freq in freqs[index]]
            )

        eig = eigs[index]

        # Eigenvectors need to be a 3Nx3N matrix in the format:
        # 1_x -> [ m_1, ..., m_3N ]
        # 1_y -> [ m_1, ..., m_3N ]
        # ...
        # N_z -> [ m_1, ..., m_3N ]

        eig_rows = []

        for i in range(0, n_at):
            for j in range(0, 3):
                eig_row = []

                for k in range(0, n_b):
                    eig_row.append(eig[k][i][j])

                eig_rows.append(eig_row)

        eig_sets.append(eig_rows)

    freq_sets = np.array(freq_sets, dtype = np.float64)
    eig_sets = np.array(eig_sets, dtype = np.complex128)

    # Use the DynmatToForceConstants object to build the dynamical matrices, reverse transform to the force constants, and write a Phonopy FORCE_CONSTANTS file.

    dynmat_to_fc.set_dynamical_matrices(freq_sets, eig_sets)

    dynmat_to_fc.run()

    write_FORCE_CONSTANTS(
        dynmat_to_fc.get_force_constants(), filename = file_path
        )
Пример #26
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")