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()
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()
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()
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
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
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
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}
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
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
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 )
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()
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() phonon2 = Phonopy(bulk, [[2, 0, 0], [0, 2, 0], [0, 0, 2]],