def test_get_supercell_nacl_snf(convcell_nacl: PhonopyAtoms, helper_methods): """Test of get_supercell using SNF by NaCl.""" cell = convcell_nacl smat = [[-1, 1, 1], [1, -1, 1], [1, 1, -1]] scell = get_supercell(cell, smat, is_old_style=True) scell_snf = get_supercell(cell, smat, is_old_style=False) helper_methods.compare_cells(scell, scell_snf)
def test_get_supercell_Cr(convcell_cr: PhonopyAtoms, helper_methods): """Test of get_supercell using SNF by Cr with magnetic moments.""" convcell_cr.magnetic_moments = [1, -1] smat = [[-1, 1, 1], [1, -1, 1], [1, 1, -1]] scell = get_supercell(convcell_cr, smat, is_old_style=True) np.testing.assert_allclose( scell.magnetic_moments, [1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0], atol=1e-8, ) scell_snf = get_supercell(convcell_cr, smat, is_old_style=False) helper_methods.compare_cells(scell, scell_snf) convcell_cr.magnetic_moments = None
def get_commensurate_points(supercell_matrix): # wrt primitive cell rec_primitive = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix.T) return rec_supercell.get_scaled_positions()
def __init__(self, dynamical_matrix, dimension, phonon_modes, delta_q=None, derivative_order=None, nac_q_direction=None, factor=VaspToTHz): """Class describe atomic modulations Atomic modulations corresponding to phonon modes are created. """ self._dm = dynamical_matrix self._primitive = dynamical_matrix.get_primitive() self._phonon_modes = phonon_modes self._dimension = dimension self._delta_q = delta_q # 1st/2nd order perturbation direction self._nac_q_direction = nac_q_direction self._ddm = DerivativeOfDynamicalMatrix(dynamical_matrix) self._derivative_order = derivative_order self._factor = factor self._u = [] self._eigvecs = [] self._eigvals = [] self._supercell = None dim = self._get_dimension_3x3() self._supercell = get_supercell(self._primitive, dim)
def _arrange_supercell_fc(self, cell, q2r_fc, is_full_fc=False): dim = self.dimension q2r_spos = self._get_q2r_positions(cell) scell = get_supercell(cell, np.diag(dim)) pcell = get_primitive(scell, np.diag(1.0 / dim)) diff = cell.get_scaled_positions() - pcell.get_scaled_positions() diff -= np.rint(diff) assert (np.abs(diff) < 1e-8).all() assert scell.get_number_of_atoms() == len(q2r_spos) site_map = self._get_site_mapping(scell.get_scaled_positions(), q2r_spos, scell.get_cell()) natom = pcell.get_number_of_atoms() ndim = np.prod(dim) natom_s = natom * ndim if is_full_fc: fc = np.zeros((natom_s, natom_s, 3, 3), dtype='double', order='C') p2s = pcell.get_primitive_to_supercell_map() fc[p2s, :] = q2r_fc[:, site_map] distribute_force_constants_by_translations(fc, pcell, scell) else: fc = np.zeros((natom, natom_s, 3, 3), dtype='double', order='C') fc[:, :] = q2r_fc[:, site_map] return fc, pcell, scell
def _extract_independent_borns(borns, ucell, primitive_matrix=None, supercell_matrix=None, is_symmetry=True, symprec=1e-5): if primitive_matrix is None: pmat = np.eye(3) else: pmat = primitive_matrix if supercell_matrix is None: smat = np.eye(3, dtype='intc') else: smat = supercell_matrix inv_smat = np.linalg.inv(smat) scell = get_supercell(ucell, smat, symprec=symprec) pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec) p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc') p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec) s_indep_atoms = p2s[p_sym.get_independent_atoms()] u2u = scell.get_unitcell_to_unitcell_map() u_indep_atoms = [u2u[x] for x in s_indep_atoms] reduced_borns = borns[u_indep_atoms].copy() return reduced_borns, s_indep_atoms
def get_born_OUTCAR( poscar_filename="POSCAR", outcar_filename="OUTCAR", primitive_axis=np.eye(3), supercell_matrix=np.eye(3, dtype="intc"), is_symmetry=True, symmetrize_tensors=False, symprec=1e-5, ): ucell = read_vasp(poscar_filename) outcar = open(outcar_filename) borns, epsilon = _read_born_and_epsilon(outcar) num_atom = len(borns) assert num_atom == ucell.get_number_of_atoms() if symmetrize_tensors: lattice = ucell.get_cell().T positions = ucell.get_scaled_positions() u_sym = Symmetry(ucell, is_symmetry=is_symmetry, symprec=symprec) point_sym = [similarity_transformation(lattice, r) for r in u_sym.get_pointgroup_operations()] epsilon = _symmetrize_tensor(epsilon, point_sym) borns = _symmetrize_borns(borns, u_sym, lattice, positions, symprec) inv_smat = np.linalg.inv(supercell_matrix) scell = get_supercell(ucell, supercell_matrix, symprec=symprec) pcell = get_primitive(scell, np.dot(inv_smat, primitive_axis), symprec=symprec) p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype="intc") p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec) s_indep_atoms = p2s[p_sym.get_independent_atoms()] u2u = scell.get_unitcell_to_unitcell_map() u_indep_atoms = [u2u[x] for x in s_indep_atoms] reduced_borns = borns[u_indep_atoms].copy() return reduced_borns, epsilon
def _set_supercell(self): supercell = get_supercell(self._unitcell, self._supercell_matrix, self._symprec) self.set_supercell(supercell) self._primitive = Primitive(supercell, np.linalg.inv(self._supercell_matrix), self._symprec)
def _prepare_unfolding(self, qpoints, unfolding_supercell_matrix): supercell = get_supercell(self._cell, np.diag([2, 2, 2])) phonon = self._get_phonon(supercell) mapping = range(supercell.get_number_of_atoms()) self._unfolding = Unfolding(phonon, unfolding_supercell_matrix, supercell.get_scaled_positions(), mapping, qpoints)
def dynmat(self, supercell, q=None, cutoff=0.1): """Returns the non-zero eigenvalues and their corresponding eigenvectors for the specified supercell. Args: supercell (numpy.ndarray): supercell matrix to use in generating the configs. q (numpy.ndarray): q-vector that the resulting supercell should be compatible with. cutoff (float): minimum value an eigenvalue should have before it is included in the set. """ #We need to determine the supercell matrix that is compatible with the #given `q` and has `N` atoms. scell = get_supercell(self.primitive, supercell) eigvals, eigvecs = self.diagonalize(q) result = { "template": phonopy_to_ase(scell), "eigvals": [], "eigvecs": [] } for i, l in enumerate(eigvals): if np.abs(l) > 0.1: meigvec = self._map_eigvec_supercell(scell, eigvecs[:, i]) result["eigvals"].append(l) result["eigvecs"].append(meigvec) return result
def __init__( self, dynamical_matrix: Union[DynamicalMatrix, DynamicalMatrixNAC], dimension, phonon_modes, delta_q=None, derivative_order=None, nac_q_direction=None, factor=VaspToTHz, ): """Init method.""" self._dm = dynamical_matrix self._primitive = dynamical_matrix.primitive self._phonon_modes = phonon_modes self._dimension = np.array(dimension).ravel() self._delta_q = delta_q # 1st/2nd order perturbation direction self._nac_q_direction = nac_q_direction self._ddm = DerivativeOfDynamicalMatrix(dynamical_matrix) self._derivative_order = derivative_order self._factor = factor dim = self._get_dimension_3x3() self._supercell = get_supercell(self._primitive, dim) complex_dtype = "c%d" % (np.dtype("double").itemsize * 2) self._u = np.zeros( (len(self._phonon_modes), len(self._supercell), 3), dtype=complex_dtype, order="C", ) self._eigvals = np.zeros(len(self._phonon_modes), dtype="double") self._eigvecs = np.zeros( (len(self._phonon_modes), len(self._primitive) * 3), dtype=complex_dtype )
def __init__(self, dynamical_matrix, dimension, phonon_modes, delta_q=None, derivative_order=None, nac_q_direction=None, factor=VaspToTHz): """Class describe atomic modulations Atomic modulations corresponding to phonon modes are created. """ self._dm = dynamical_matrix self._primitive = dynamical_matrix.get_primitive() self._phonon_modes = phonon_modes self._dimension = dimension self._delta_q = delta_q # 1st/2nd order perturbation direction self._nac_q_direction = nac_q_direction self._ddm = DerivativeOfDynamicalMatrix(dynamical_matrix) self._derivative_order = derivative_order self._factor = factor self._u = [] self._eigvecs = [] self._eigvals = [] self._supercell = None dim = self._get_dimension_3x3() self._supercell = get_supercell(self._primitive, dim)
def _arrange_supercell_fc(self, cell, q2r_fc, is_full_fc=False): dim = self.dimension q2r_spos = self._get_q2r_positions(cell) scell = get_supercell(cell, np.diag(dim)) pcell = get_primitive(scell, np.diag(1.0 / dim)) diff = cell.get_scaled_positions() - pcell.get_scaled_positions() diff -= np.rint(diff) assert (np.abs(diff) < 1e-8).all() assert scell.get_number_of_atoms() == len(q2r_spos) site_map = self._get_site_mapping(scell.get_scaled_positions(), q2r_spos, scell.get_cell()) natom = pcell.get_number_of_atoms() ndim = np.prod(dim) natom_s = natom * ndim if is_full_fc: fc = np.zeros((natom_s, natom_s, 3, 3), dtype='double', order='C') p2s = pcell.get_primitive_to_supercell_map() fc[p2s, :] = q2r_fc[:, site_map] distribute_force_constants_by_translations(fc, pcell, scell) else: fc = np.zeros((natom, natom_s, 3, 3), dtype='double', order='C') fc[:, :] = q2r_fc[:, site_map] return fc, pcell, scell
def ph2fc(ph_orig, supercell_matrix): """Transform force constants in Phonopy instance to other shape For example, ph_orig.supercell_matrix is np.diag([2, 2, 2]) and supercell_matrix is np.diag([4, 4, 4]), force constants having the later shape are returned. This is considered useful when ph_orig has non-analytical correction (NAC). The effect of this correction is included in the returned force constants. Phonons before and after this operation at commensurate points of the later supercell_matrix should agree. """ smat = shape_supercell_matrix(supercell_matrix) scell = get_supercell(ph_orig.unitcell, smat) pcell = get_primitive( scell, np.dot(np.linalg.inv(smat), ph_orig.primitive_matrix), positions_to_reorder=ph_orig.primitive.scaled_positions) d2f = DynmatToForceConstants(pcell, scell) ph_orig.run_qpoints(d2f.commensurate_points, with_dynamical_matrices=True) ph_dict = ph_orig.get_qpoints_dict() d2f.dynamical_matrices = ph_dict['dynamical_matrices'] d2f.run() return d2f.force_constants
def get_commensurate_points(supercell_matrix): # wrt primitive cell """Commensurate q-points are returned. Parameters ---------- supercell_matrix : array_like Supercell matrix with respect to primitive cell basis vectors. shape=(3, 3), dtype=int Returns ------- commensurate_points : ndarray Commensurate points corresponding to supercell matrix. shape=(N, 3), dtype='double', order='C' where N = det(supercell_matrix) """ smat = np.array(supercell_matrix, dtype=int) rec_primitive = PhonopyAtoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, smat.T) q_pos = rec_supercell.scaled_positions return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos), dtype='double', order='C')
def _extract_independent_borns(borns, ucell, primitive_matrix=None, supercell_matrix=None, is_symmetry=True, symprec=1e-5): if primitive_matrix is None: pmat = np.eye(3) else: pmat = primitive_matrix if supercell_matrix is None: smat = np.eye(3, dtype='intc') else: smat = supercell_matrix inv_smat = np.linalg.inv(smat) scell = get_supercell(ucell, smat, symprec=symprec) pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec) p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc') p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec) s_indep_atoms = p2s[p_sym.get_independent_atoms()] u2u = scell.get_unitcell_to_unitcell_map() u_indep_atoms = [u2u[x] for x in s_indep_atoms] reduced_borns = borns[u_indep_atoms].copy() return reduced_borns, s_indep_atoms
def _set_supercell(self): supercell = get_supercell(self._unitcell, self._supercell_matrix, self._symprec) self.set_supercell(supercell) self._primitive = Primitive(supercell, np.linalg.inv(self._supercell_matrix), self._symprec)
def get_commensurate_points(primitive, supercell): supercell_matrix = np.linalg.inv(primitive.get_primitive_matrix()).T rec_primitive = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix) return rec_supercell.get_scaled_positions()
def get_commensurate_points(primitive, supercell): supercell_matrix = np.linalg.inv(primitive.get_primitive_matrix()).T rec_primitive = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix) return rec_supercell.get_scaled_positions()
def _prepare_unfolding(self, qpoints, unfolding_supercell_matrix): supercell = get_supercell(self._cell, np.diag([2, 2, 2])) phonon = self._get_phonon(supercell) self._set_nac_params(phonon) mapping = range(supercell.get_number_of_atoms()) self._unfolding = Unfolding( phonon, unfolding_supercell_matrix, supercell.get_scaled_positions(), mapping, qpoints )
def test_get_commensurate_points(self): smat = np.diag([2, 2, 2]) pmat = np.dot(np.linalg.inv(smat), [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) supercell = get_supercell(self._cell, smat) primitive = get_primitive(supercell, pmat) comm_points = get_commensurate_points(primitive, supercell) for i, p in enumerate(comm_points): print("%d %s" % (i + 1, p))
def test_get_primitive_convcell_Cr(convcell_cr: PhonopyAtoms, helper_methods): """Test get_primitive by NaCl.""" convcell_cr.magnetic_moments = [1, -1] smat = [[2, 0, 0], [0, 2, 0], [0, 0, 2]] scell = get_supercell(convcell_cr, smat, is_old_style=True) pmat = np.linalg.inv(smat) pcell = get_primitive(scell, pmat) helper_methods.compare_cells(convcell_cr, pcell) convcell_cr.magnetic_moments = None
def test_get_commensurate_points(self): smat = np.diag([2, 2, 2]) pmat = np.dot(np.linalg.inv(smat), [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) supercell = get_supercell(self._cell, smat) primitive = get_primitive(supercell, pmat) comm_points = get_commensurate_points(primitive, supercell) for i, p in enumerate(comm_points): print("%d %s" % (i + 1, p))
def _set_translations(self): pcell = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) smat = self._supercell_matrix self._trans_s = get_supercell(pcell, smat).get_scaled_positions() self._trans_p = np.dot(self._trans_s, self._supercell_matrix.T) self._N = len(self._trans_s)
def _set_translations(self): pcell = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) smat = self._supercell_matrix self._trans_s = get_supercell(pcell, smat).get_scaled_positions() self._trans_p = np.dot(self._trans_s, self._supercell_matrix.T) self._N = len(self._trans_s)
def get_commensurate_points(supercell_matrix): # wrt primitive cell rec_primitive = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix.T) q_pos = rec_supercell.get_scaled_positions() return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos), dtype='double', order='C')
def get_commensurate_points(supercell_matrix): # wrt primitive cell rec_primitive = PhonopyAtoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix.T) q_pos = rec_supercell.get_scaled_positions() return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos), dtype='double', order='C')
def test_get_commensurate_points(self): smat = np.diag([2, 2, 2]) pmat = np.dot(np.linalg.inv(smat), [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) supercell = get_supercell(self._cell, smat) primitive = get_primitive(supercell, pmat) supercell_matrix = np.linalg.inv(primitive.get_primitive_matrix()) supercell_matrix = np.rint(supercell_matrix).astype('intc') comm_points = get_commensurate_points(supercell_matrix) # self._write(comm_points) self._compare(comm_points)
def _test_get_supercell_primcell_si(primcell_si: PhonopyAtoms, helper_methods, is_old_style=True): smat = [[-1, 1, 1], [1, -1, 1], [1, 1, -1]] fname = "Si-conv.yaml" scell = get_supercell(primcell_si, smat, is_old_style=is_old_style) cell_ref = read_cell_yaml(os.path.join(data_dir, fname)) if is_old_style is True: helper_methods.compare_cells_with_order(scell, cell_ref) else: helper_methods.compare_cells(scell, cell_ref)
def _test_get_supercell_convcell_sio2(convcell_sio2: PhonopyAtoms, helper_methods, is_old_style=True): smat = np.diag([1, 2, 3]) fname = "SiO2-123.yaml" scell = get_supercell(convcell_sio2, smat, is_old_style=is_old_style) cell_ref = read_cell_yaml(os.path.join(data_dir, fname)) if is_old_style is True: helper_methods.compare_cells_with_order(scell, cell_ref) else: helper_methods.compare_cells(scell, cell_ref)
def test_get_commensurate_points(self): smat = np.diag([2, 2, 2]) pmat = np.dot(np.linalg.inv(smat), [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]) supercell = get_supercell(self._cell, smat) primitive = get_primitive(supercell, pmat) supercell_matrix = np.linalg.inv(primitive.get_primitive_matrix()) supercell_matrix = np.rint(supercell_matrix).astype('intc') comm_points = get_commensurate_points(supercell_matrix) # self._write(comm_points) self._compare(comm_points)
def _build_phonon_supercell(self): """ phonon_supercell: This supercell is used for harmonic phonons (frequencies, eigenvectors, group velocities, ...) phonon_supercell_matrix: Different supercell size can be specified. """ if self._phonon_supercell_matrix is None: self._phonon_supercell = self._supercell else: self._phonon_supercell = get_supercell(self._unitcell, self._phonon_supercell_matrix, self._symprec)
def _build_phonon_supercell(self): """ phonon_supercell: This supercell is used for harmonic phonons (frequencies, eigenvectors, group velocities, ...) phonon_supercell_matrix: Different supercell size can be specified. """ if self._phonon_supercell_matrix is None: self._phonon_supercell = self._supercell else: self._phonon_supercell = get_supercell( self._unitcell, self._phonon_supercell_matrix, self._symprec)
def setUp(self): pmat = [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]] smat2 = np.eye(3, dtype='intc') * 2 pmat2 = np.dot(np.linalg.inv(smat2), pmat) smat3 = np.eye(3, dtype='intc') * 3 pmat3 = np.dot(np.linalg.inv(smat3), pmat) cell = read_cell_yaml(os.path.join(data_dir, "..", "NaCl.yaml")) scell2 = get_supercell(cell, smat2) scell3 = get_supercell(cell, smat3) n = len(scell3) // 2 # swap first and last half of atomic order indices = [i + n for i in range(n)] + list(range(n)) scell3_swap = PhonopyAtoms( cell=scell3.cell, scaled_positions=scell3.scaled_positions[indices], numbers=scell3.numbers[indices]) self._tcell2 = TrimmedCell(pmat2, scell2) self._tcell3 = TrimmedCell( pmat3, scell3_swap, positions_to_reorder=self._tcell2.scaled_positions)
def test_TrimmedCell(convcell_nacl, helper_methods): pmat = [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]] smat2 = np.eye(3, dtype='intc') * 2 pmat2 = np.dot(np.linalg.inv(smat2), pmat) smat3 = np.eye(3, dtype='intc') * 3 pmat3 = np.dot(np.linalg.inv(smat3), pmat) cell = convcell_nacl scell2 = get_supercell(cell, smat2) scell3 = get_supercell(cell, smat3) n = len(scell3) // 2 # swap first and last half of atomic order indices = [i + n for i in range(n)] + list(range(n)) scell3_swap = PhonopyAtoms( cell=scell3.cell, scaled_positions=scell3.scaled_positions[indices], numbers=scell3.numbers[indices]) tcell2 = TrimmedCell(pmat2, scell2) tcell3 = TrimmedCell(pmat3, scell3_swap, positions_to_reorder=tcell2.scaled_positions) helper_methods.compare_cells_with_order(tcell2, tcell3)
def get_BORN_txt(structure, parameters, nac_data, symprec=1.e-5): from phonopy.structure.cells import get_primitive, get_supercell from phonopy.structure.symmetry import Symmetry from phonopy.interface import get_default_physical_units from phonopy.structure.atoms import Atoms as PhonopyAtoms born_charges = nac_data.get_array('born_charges') epsilon = nac_data.get_array('epsilon') print ('inside born parameters') pmat = parameters['primitive'] smat = parameters['supercell'] ucell = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites], positions=[site.position for site in structure.sites], cell=structure.cell) num_atom = len(born_charges) assert num_atom == ucell.get_number_of_atoms(), \ "num_atom %d != len(borns) %d" % (ucell.get_number_of_atoms(), len(born_charges)) inv_smat = np.linalg.inv(smat) scell = get_supercell(ucell, smat, symprec=symprec) pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec) p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc') p_sym = Symmetry(pcell, is_symmetry=True, symprec=symprec) s_indep_atoms = p2s[p_sym.get_independent_atoms()] u2u = scell.get_unitcell_to_unitcell_map() u_indep_atoms = [u2u[x] for x in s_indep_atoms] reduced_borns = born_charges[u_indep_atoms].copy() factor = get_default_physical_units('vasp')['nac_factor'] # born charges in VASP units born_txt = ('{}\n'.format(factor)) for num in epsilon.flatten(): born_txt += ('{0:4.8f}'.format(num)) born_txt += ('\n') for atom in reduced_borns: for num in atom: born_txt += ('{0:4.8f}'.format(num)) born_txt += ('\n') born_txt += ('{}\n'.format(factor)) return born_txt
def _get_delta(self, eigvec, q): dim = self._get_dimension_3x3() supercell = get_supercell(self._primitive, dim) m = supercell.get_masses() s2u_map = supercell.get_supercell_to_unitcell_map() u2u_map = supercell.get_unitcell_to_unitcell_map() s2uu_map = [u2u_map[x] for x in s2u_map] spos = supercell.get_scaled_positions() coefs = np.exp(2j * np.pi * np.dot(np.dot(spos, dim.T), q)) / np.sqrt(m) u = [] for i, coef in enumerate(coefs): eig_index = s2uu_map[i] * 3 u.append(eigvec[eig_index:eig_index + 3] * coef) self._supercell = supercell return np.array(u)
def _get_delta(self, eigvec, q): dim = self._get_dimension_3x3() supercell = get_supercell(self._primitive, dim) m = supercell.get_masses() s2u_map = supercell.get_supercell_to_unitcell_map() u2u_map = supercell.get_unitcell_to_unitcell_map() s2uu_map = [u2u_map[x] for x in s2u_map] spos = supercell.get_scaled_positions() coefs = np.exp( 2j * np.pi * np.dot(np.dot(spos, dim.T), q)) / np.sqrt(m) u = [] for i, coef in enumerate(coefs): eig_index = s2uu_map[i] * 3 u.append(eigvec[eig_index:eig_index + 3] * coef) self._supercell = supercell return np.array(u)
def test_get_supercell(self): for i, (cell, smat, fname) in enumerate(zip(self._cells, self._smats, self._fnames)): scell = get_supercell(cell, smat) scell_yaml = read_cell_yaml(os.path.join(data_dir, fname)) np.testing.assert_allclose(scell.get_cell(), scell_yaml.get_cell(), atol=1e-5) pos = scell.get_scaled_positions() pos -= np.rint(pos) pos_yaml = scell_yaml.get_scaled_positions() pos_yaml -= np.rint(pos_yaml) np.testing.assert_allclose(pos, pos_yaml, atol=1e-5) np.testing.assert_array_equal(scell.get_atomic_numbers(), scell_yaml.get_atomic_numbers()) np.testing.assert_allclose(scell.get_masses(), scell_yaml.get_masses(), atol=1e-5)
def _get_supercell_and_primitive(ucell, primitive_matrix=None, supercell_matrix=None, symprec=1e-5): if primitive_matrix is None: pmat = np.eye(3) else: pmat = primitive_matrix if supercell_matrix is None: smat = np.eye(3, dtype='intc') else: smat = supercell_matrix inv_smat = np.linalg.inv(smat) scell = get_supercell(ucell, smat, symprec=symprec) pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec) return scell, pcell
def _set_translations(self): """Set primitive translations in supercell. _trans_s Translations with respect to supercell basis vectors _trans_p Translations with respect to primitive cell basis vectors _N Number of the translations = det(supercel_matrix) """ pcell = PhonopyAtoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1])) smat = self._supercell_matrix self._trans_s = get_supercell(pcell, smat).scaled_positions self._trans_p = np.dot(self._trans_s, self._supercell_matrix.T) self._N = len(self._trans_s)
def _get_supercell_and_primitive(ucell, primitive_matrix=None, supercell_matrix=None, symprec=1e-5): if primitive_matrix is None: pmat = np.eye(3) else: pmat = primitive_matrix if supercell_matrix is None: smat = np.eye(3, dtype="intc") else: smat = supercell_matrix inv_smat = np.linalg.inv(smat) scell = get_supercell(ucell, smat, symprec=symprec) pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec) return scell, pcell
def get_born_OUTCAR(poscar_filename="POSCAR", outcar_filename="OUTCAR", primitive_matrix=None, supercell_matrix=None, is_symmetry=True, symmetrize_tensors=False, symprec=1e-5): if primitive_matrix is None: pmat = np.eye(3) else: pmat = primitive_matrix if supercell_matrix is None: smat = np.eye(3, dtype='intc') else: smat = supercell_matrix ucell = read_vasp(poscar_filename) outcar = open(outcar_filename) borns, epsilon = _read_born_and_epsilon(outcar) num_atom = len(borns) assert num_atom == ucell.get_number_of_atoms() if symmetrize_tensors: lattice = ucell.get_cell().T positions = ucell.get_scaled_positions() u_sym = Symmetry(ucell, is_symmetry=is_symmetry, symprec=symprec) point_sym = [ similarity_transformation(lattice, r) for r in u_sym.get_pointgroup_operations() ] epsilon = _symmetrize_tensor(epsilon, point_sym) borns = _symmetrize_borns(borns, u_sym, lattice, positions, symprec) inv_smat = np.linalg.inv(smat) scell = get_supercell(ucell, smat, symprec=symprec) pcell = get_primitive(scell, np.dot(inv_smat, pmat), symprec=symprec) p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc') p_sym = Symmetry(pcell, is_symmetry=is_symmetry, symprec=symprec) s_indep_atoms = p2s[p_sym.get_independent_atoms()] u2u = scell.get_unitcell_to_unitcell_map() u_indep_atoms = [u2u[x] for x in s_indep_atoms] reduced_borns = borns[u_indep_atoms].copy() return reduced_borns, epsilon, s_indep_atoms
def _set_translations(self): """Set primitive translations in supercell _trans_s Translations with respect to supercell basis vectors _trans_p Translations with respect to primitive cell basis vectors _N Number of the translations = det(supercel_matrix) """ pcell = PhonopyAtoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1])) smat = self._supercell_matrix self._trans_s = get_supercell(pcell, smat).get_scaled_positions() self._trans_p = np.dot(self._trans_s, self._supercell_matrix.T) self._N = len(self._trans_s)
def test_get_map_operations(self): symprec = 1e-5 cell = read_cell_yaml(os.path.join(data_dir, "..", "NaCl.yaml")) scell = get_supercell(cell, np.diag([2, 2, 2]), symprec=symprec) symmetry = Symmetry(scell, symprec=symprec) # start = time.time() symmetry._set_map_operations() # end = time.time() # print(end - start) map_ops = symmetry.get_map_operations() map_atoms = symmetry.get_map_atoms() positions = scell.get_scaled_positions() rotations = symmetry.get_symmetry_operations()['rotations'] translations = symmetry.get_symmetry_operations()['translations'] for i, (op_i, atom_i) in enumerate(zip(map_ops, map_atoms)): r_pos = np.dot(rotations[op_i], positions[i]) + translations[op_i] diff = positions[atom_i] - r_pos diff -= np.rint(diff) self.assertTrue((diff < symprec).all())
def test_get_map_operations(self): symprec = 1e-5 cell = get_unitcell_from_phonopy_yaml( os.path.join(data_dir,"../NaCl.yaml")) scell = get_supercell(cell, np.diag([2, 2, 2]), symprec=symprec) symmetry = Symmetry(scell, symprec=symprec) start = time.time() symmetry._set_map_operations() end = time.time() # print(end - start) map_ops = symmetry.get_map_operations() map_atoms = symmetry.get_map_atoms() positions = scell.get_scaled_positions() rotations = symmetry.get_symmetry_operations()['rotations'] translations = symmetry.get_symmetry_operations()['translations'] for i, (op_i, atom_i) in enumerate(zip(map_ops, map_atoms)): r_pos = np.dot(rotations[op_i], positions[i]) + translations[op_i] diff = positions[atom_i] - r_pos diff -= np.rint(diff) self.assertTrue((diff < symprec).all())
def get_commensurate_points(supercell_matrix): # wrt primitive cell """Commensurate q-points are returned. Parameters ---------- supercell_matrix : array_like Supercell matrix with respect to primitive cell basis vectors. shape=(3, 3) dtype=intc """ smat = np.array(supercell_matrix, dtype=int) rec_primitive = PhonopyAtoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, smat.T) q_pos = rec_supercell.get_scaled_positions() return np.array(np.where(q_pos > 1 - 1e-15, q_pos - 1, q_pos), dtype='double', order='C')
def _arrange_supercell_fc(self, cell, q2r_fc): dim = self.dimension q2r_spos = self._get_q2r_positions(cell) scell = get_supercell(cell, np.diag(dim)) assert scell.get_number_of_atoms() == len(q2r_spos) site_map = self._get_site_mapping(scell.get_scaled_positions(), q2r_spos, scell.get_cell()) natom = cell.get_number_of_atoms() ndim = np.prod(dim) natom_s = natom * ndim # full force constants # fc = np.zeros((natom_s, natom_s, 3, 3), dtype='double', order='C') # s_indices = [np.where(site_map==(i * ndim))[0][0] for i in range(natom)] # for i, si in enumerate(s_indices): # fc[si, :] = q2r_fc[i, site_map] # self._distribute_fc2(fc, s_indices, scell) # compact force constants fc = np.zeros((natom, natom_s, 3, 3), dtype='double', order='C') fc[:, :] = q2r_fc[:, site_map] return fc
def get_born_OUTCAR(poscar_filename="POSCAR", outcar_filename="OUTCAR", primitive_axis=np.eye(3), supercell_matrix=np.eye(3, dtype='intc'), is_symmetry=True, symmetrize_tensors=False): ucell = read_vasp(poscar_filename) scell = get_supercell(ucell, supercell_matrix) inv_smat = np.linalg.inv(supercell_matrix) pcell = get_primitive(scell, np.dot(inv_smat, primitive_axis)) u_sym = Symmetry(ucell, is_symmetry=is_symmetry) p_sym = Symmetry(pcell, is_symmetry=is_symmetry) lattice = ucell.get_cell().T outcar = open(outcar_filename) borns = [] while True: line = outcar.readline() if not line: break if "NIONS" in line: num_atom = int(line.split()[11]) if "MACROSCOPIC STATIC DIELECTRIC TENSOR" in line: epsilon = [] outcar.readline() epsilon.append([float(x) for x in outcar.readline().split()]) epsilon.append([float(x) for x in outcar.readline().split()]) epsilon.append([float(x) for x in outcar.readline().split()]) if "BORN" in line: outcar.readline() line = outcar.readline() if "ion" in line: for i in range(num_atom): born = [] born.append([float(x) for x in outcar.readline().split()][1:]) born.append([float(x) for x in outcar.readline().split()][1:]) born.append([float(x) for x in outcar.readline().split()][1:]) outcar.readline() borns.append(born) borns = np.array(borns, dtype='double') epsilon = np.array(epsilon, dtype='double') if symmetrize_tensors: borns_orig = borns.copy() point_sym = [similarity_transformation(lattice, r) for r in u_sym.get_pointgroup_operations()] epsilon = symmetrize_tensor(epsilon, point_sym) for i in range(num_atom): z = borns[i] site_sym = [similarity_transformation(lattice, r) for r in u_sym.get_site_symmetry(i)] borns[i] = symmetrize_tensor(z, site_sym) rotations = u_sym.get_symmetry_operations()['rotations'] map_atoms = u_sym.get_map_atoms() borns_copy = np.zeros_like(borns) for i, m_i in enumerate(map_atoms): count = 0 for j, r_j in enumerate(u_sym.get_map_operations()): if map_atoms[j] == m_i: count += 1 r_cart = similarity_transformation(lattice, rotations[r_j]) borns_copy[i] += similarity_transformation(r_cart, borns[j]) borns_copy[i] /= count borns = borns_copy sum_born = borns.sum(axis=0) / len(borns) borns -= sum_born if (np.abs(borns_orig - borns) > 0.1).any(): sys.stderr.write( "Born effective charge symmetrization might go wrong.\n") p2s = np.array(pcell.get_primitive_to_supercell_map(), dtype='intc') s_indep_atoms = p2s[p_sym.get_independent_atoms()] u2u = scell.get_unitcell_to_unitcell_map() u_indep_atoms = [u2u[x] for x in s_indep_atoms] reduced_borns = borns[u_indep_atoms].copy() return reduced_borns, epsilon
def _build_supercell(self): self._supercell = get_supercell(self._unitcell, self._supercell_matrix, self._symprec)
def __supercell(self): self.supercell = get_supercell( self.unitcell, self.supercell_matrix, self.symprec )
def get_commensurate_points(supercell_matrix): # wrt primitive cell rec_primitive = Atoms(numbers=[1], scaled_positions=[[0, 0, 0]], cell=np.diag([1, 1, 1]), pbc=True) rec_supercell = get_supercell(rec_primitive, supercell_matrix.T) return rec_supercell.get_scaled_positions()