def _set_phonon(self): if self._supercell_matrix is None: cell = sort_cell_by_symbols( get_crystallographic_cell(self.get_cell())) self._supercell_matrix = estimate_supercell_matrix( cell, max_num_atoms=self._max_num_atoms) else: cell = self.get_cell() phonopy_cell = cell2atoms(cell) self._phonon = Phonopy(phonopy_cell, self._supercell_matrix, primitive_matrix=self._primitive_matrix, dynamical_matrix_decimals=14, force_constants_decimals=14, symprec=self._symmetry_tolerance) self._phonon.generate_displacements( distance=self._distance, is_plusminus=self._displace_plusminus, is_diagonal=self._displace_diagonal) supercell = self._phonon.get_supercell() displacements = self._phonon.get_displacements() write_poscar(cell, filename="POSCAR-unitcell") write_poscar_yaml(cell, filename="POSCAR-unitcell.yaml") write_disp_yaml(displacements, supercell)
def get_displaced_structures(pmg_structure, atom_disp=0.01, supercell_matrix=None, yaml_fname=None, **kwargs): """ Generate a set of symmetrically inequivalent displaced structures for phonon calculations. Args: pmg_structure (Structure): A pymatgen structure object. atom_disp (float): Atomic displacement. Default is 0.01 $\\AA$. supercell_matrix (3x3 array): Scaling matrix for supercell. yaml_fname (string): If not None, it represents the full path to the outputting displacement yaml file, e.g. disp.yaml. **kwargs: Parameters used in Phonopy.generate_displacement method. Return: A list of symmetrically inequivalent structures with displacements, in which the first element is the perfect supercell structure. """ is_plusminus = kwargs.get("is_plusminus", "auto") is_diagonal = kwargs.get("is_diagonal", True) is_trigonal = kwargs.get("is_trigonal", False) ph_structure = get_phonopy_structure(pmg_structure) if supercell_matrix is None: supercell_matrix = np.eye(3) * np.array((1, 1, 1)) phonon = Phonopy(unitcell=ph_structure, supercell_matrix=supercell_matrix) phonon.generate_displacements(distance=atom_disp, is_plusminus=is_plusminus, is_diagonal=is_diagonal, is_trigonal=is_trigonal) if yaml_fname is not None: displacements = phonon.get_displacements() directions = phonon.get_displacement_directions() write_disp_yaml(displacements=displacements, supercell=phonon.get_supercell(), directions=directions, filename=yaml_fname) # Supercell structures with displacement disp_supercells = phonon.get_supercells_with_displacements() # Perfect supercell structure init_supercell = phonon.get_supercell() # Structure list to be returned structure_list = [get_pmg_structure(init_supercell)] for c in disp_supercells: if c is not None: structure_list.append(get_pmg_structure(c)) return structure_list
def _set_phonon(self): cell = self.get_cell() phonopy_cell = Atoms(cell=cell.get_lattice().T, scaled_positions=cell.get_points().T, symbols=cell.get_symbols()) self._phonon = Phonopy(phonopy_cell, self._supercell_matrix, is_auto_displacements=False) self._phonon.generate_displacements(distance=self._distance, is_diagonal=False) supercell = self._phonon.get_supercell() displacements = self._phonon.get_displacements() write_poscar(cell, "POSCAR-unitcell") write_disp_yaml(displacements, supercell)
def _set_phonon(self): cell = self.get_cell() phonopy_cell = cell2atoms(cell) self._phonon = Phonopy(phonopy_cell, self._supercell_matrix, primitive_matrix=self._primitive_matrix, is_auto_displacements=False, dynamical_matrix_decimals=14, force_constants_decimals=14) self._phonon.generate_displacements( distance=self._distance, is_plusminus=self._displace_plusminus, is_diagonal=self._displace_diagonal) supercell = self._phonon.get_supercell() displacements = self._phonon.get_displacements() write_poscar(cell, "POSCAR-unitcell") write_disp_yaml(displacements, supercell)
def _set_phonon(self): cell = self.get_cell() phonopy_cell = Atoms( cell=cell.get_lattice().T, scaled_positions=cell.get_points().T, symbols=cell.get_symbols()) self._phonon = Phonopy(phonopy_cell, self._supercell_matrix, is_auto_displacements=False) self._phonon.generate_displacements(distance=self._distance, is_diagonal=False) supercell = self._phonon.get_supercell() displacements = self._phonon.get_displacements() write_poscar(cell, "POSCAR-unitcell") write_disp_yaml(displacements, supercell)
def _set_phonon_fc3(self): cell = self.get_cell() phonopy_cell = cell2atoms(cell) self._phonon = Phonopy(phonopy_cell, self._supercell_matrix, primitive_matrix=self._primitive_matrix, dynamical_matrix_decimals=14, force_constants_decimals=14) self._phonon_fc3 = Phono3py(phonopy_cell, self._supercell_matrix, primitive_matrix=self._primitive_matrix) self._phonon_fc3.generate_displacements(distance=self._distance, is_diagonal=self._is_diagonal) supercell = self._phonon_fc3.get_supercell() disp_dataset = self._phonon_fc3.get_displacement_dataset() self._phonon.set_displacement_dataset(disp_dataset) write_poscar(cell, "POSCAR-unitcell") write_disp_yaml(self._phonon.get_displacements(), supercell, directions=self._phonon.get_displacement_directions()) write_disp_fc3_yaml(disp_dataset, supercell)
def on_all_ok(self): """ This method is called once the `Work` is completed i.e. when all the tasks have reached status S_OK. Here we get the forces from the output files, and we call phonopy to compute the inter-atomic force constants. """ phonon = self.phonon # Write POSCAR with initial unit cell. structure = structure_from_atoms(phonon.get_primitive()) structure.to(filename=self.outdir.path_in("POSCAR")) # Write yaml file with displacements. supercell = phonon.get_supercell() displacements = phonon.get_displacements() #directions = phonon.get_displacement_directions() file_IO.write_disp_yaml(displacements, supercell, # directions=directions, filename=self.outdir.path_in('disp.yaml')) # Extract forces from the main Abinit output files. forces_filenames = [task.output_file.path for task in self.phonopy_tasks] num_atoms = supercell.get_number_of_atoms() force_sets = parse_set_of_forces(num_atoms, forces_filenames) # Write FORCE_SETS file. displacements = file_IO.parse_disp_yaml(filename=self.outdir.path_in('disp.yaml')) num_atoms = displacements['natom'] for forces, disp in zip(force_sets, displacements['first_atoms']): disp['forces'] = forces file_IO.write_FORCE_SETS(displacements, filename=self.outdir.path_in('FORCE_SETS')) # Write README and configuration files. examples_url = "http://atztogo.github.io/phonopy/examples.html" doctags_url = "http://atztogo.github.io/phonopy/setting-tags.html#setting-tags" kptbounds = np.array([k.frac_coords for k in structure.hsym_kpoints]) path_coords = " ".join(str(rc) for rc in kptbounds.flat) path_labels = " ".join(k.name for k in structure.hsym_kpoints) ngqpt = structure.calc_ngkpt(nksmall=30) with open(self.outdir.path_in("band.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("BAND = %s\n" % path_coords) fh.write("BAND_LABELS = %s\n" % path_labels) fh.write("BAND_POINTS = 101\n") fh.write("#BAND_CONNECTION = .TRUE.\n") with open(self.outdir.path_in("dos.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("MP = %d %d %d\n" % tuple(ngqpt)) fh.write("#GAMMA_CENTER = .TRUE.\n") with open(self.outdir.path_in("band-dos.conf"), "wt") as fh: fh.write("#" + doctags_url + "\n") fh.write("DIM = %d %d %d\n" % tuple(self.scdims)) fh.write("BAND = %s\n" % path_coords) fh.write("BAND_LABELS = %s\n" % path_labels) fh.write("BAND_POINTS = 101\n") fh.write("#BAND_CONNECTION = .TRUE.\n") fh.write("MP = %d %d %d\n" % tuple(ngqpt)) fh.write("#GAMMA_CENTER = .TRUE.\n") with open(self.outdir.path_in("README.md"), "wt") as fh: fh.write("To plot bands, use:\n\tphonopy -p band.conf\n\n") fh.write("To plot phonon dos, use:\n\tphonopy -p dos.conf\n\n") fh.write("To plot bands and dos, use:\n\tphonopy -p band-dos.conf\n\n") fh.write("See also:\n") fh.write("\t" + examples_url + "\n") fh.write("\t" + doctags_url + "\n") if self.cpdata2dst: self.outdir.copy_r(self.cpdata2dst) return super(PhonopyWork, self).on_all_ok()