Esempio n. 1
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
Esempio n. 2
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
Esempio n. 3
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
Esempio n. 4
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()
Esempio n. 5
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()
Esempio n. 6
0
 def _set_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]),
                                  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 > 2:
             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()
Esempio n. 7
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'])
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
        )
Esempio n. 9
0
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()

phonon2 = 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)
phonon2.set_force_constants(fc)
bands = []
append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.0, 0.0])
append_band(bands, [0.5, 0.0, 0.0], [0.5, 0.5, 0.0])
Esempio n. 10
0
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()

phonon2 = 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)
phonon2.set_force_constants(fc)
bands = []
append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.0, 0.0])
append_band(bands, [0.5, 0.0, 0.0], [0.5, 0.5, 0.0])
append_band(bands, [0.5, 0.5, 0.0], [0.0, 0.0, 0.0])
append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.5, 0.5])
phonon2.set_band_structure(bands)
phonon2.plot_band_structure().show()