def produce_fc2(self, forces_fc2, displacement_dataset=None, symmetrize_fc2=False, is_compact_fc=False, use_alm=False): if displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = displacement_dataset if use_alm: from phono3py.other.alm_wrapper import get_fc2 as get_fc2_alm self._fc2 = get_fc2_alm(self._phonon_supercell, forces_fc2, disp_dataset, self._phonon_supercell_symmetry) else: for forces, disp1 in zip(forces_fc2, disp_dataset['first_atoms']): disp1['forces'] = forces if is_compact_fc: p2s_map = self._phonon_primitive.get_primitive_to_supercell_map( ) else: p2s_map = None self._fc2 = get_fc2(self._phonon_supercell, self._phonon_supercell_symmetry, disp_dataset, atom_list=p2s_map) if symmetrize_fc2: if is_compact_fc: symmetrize_compact_force_constants(self._fc2, self._phonon_primitive) else: symmetrize_force_constants(self._fc2)
def _read_phono3py_fc2(phono3py, symmetrize_fc2, input_filename, log_level): if input_filename is None: filename = "fc2.hdf5" else: filename = "fc2." + input_filename + ".hdf5" file_exists(filename, log_level) if log_level: print('Reading fc2 from "%s".' % filename) num_atom = phono3py.phonon_supercell.get_number_of_atoms() p2s_map = phono3py.phonon_primitive.p2s_map try: phonon_fc2 = read_fc2_from_hdf5(filename=filename, p2s_map=p2s_map) except RuntimeError: import traceback traceback.print_exc() if log_level: print_error() sys.exit(1) if phonon_fc2.shape[1] != num_atom: print("Matrix shape of fc2 doesn't agree with supercell size.") if log_level: print_error() sys.exit(1) if symmetrize_fc2: if phonon_fc2.shape[0] == phonon_fc2.shape[1]: symmetrize_force_constants(phonon_fc2) else: symmetrize_compact_force_constants(phonon_fc2, phono3py.phonon_primitive) phono3py.fc2 = phonon_fc2
def _extract_fc_list(self): fc_list = [] for fc_filename in self._fc_filenames: force_constants = parse_FORCE_CONSTANTS(fc_filename) symmetrize_force_constants(force_constants) fc_list.append(force_constants) return fc_list
def produce_fc3( self, forces_fc3, displacement_dataset=None, cutoff_distance=None, # set fc3 zero symmetrize_fc3r=False, is_compact_fc=False, use_alm=False, alm_options=None): if displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = displacement_dataset if use_alm: from phono3py.other.alm_wrapper import get_fc3 as get_fc3_alm fc2, fc3 = get_fc3_alm(self._supercell, self._primitive, forces_fc3, disp_dataset, self._symmetry, alm_options=alm_options, is_compact_fc=is_compact_fc, log_level=self._log_level) else: fc2, fc3 = self._get_fc3(forces_fc3, disp_dataset, is_compact_fc=is_compact_fc) if symmetrize_fc3r: if is_compact_fc: set_translational_invariance_compact_fc3( fc3, self._primitive) set_permutation_symmetry_compact_fc3(fc3, self._primitive) if self._fc2 is None: symmetrize_compact_force_constants( fc2, self._primitive) else: set_translational_invariance_fc3(fc3) set_permutation_symmetry_fc3(fc3) if self._fc2 is None: symmetrize_force_constants(fc2) # Set fc2 and fc3 self._fc3 = fc3 # Normally self._fc2 is overwritten in produce_fc2 if self._fc2 is None: self._fc2 = fc2
def produce_fc2(self, forces_fc2, displacement_dataset=None, symmetrize_fc2=False, is_compact_fc=False, use_alm=False, alm_options=None): if displacement_dataset is None: if self._phonon_displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = self._phonon_displacement_dataset else: disp_dataset = displacement_dataset for forces, disp1 in zip(forces_fc2, disp_dataset['first_atoms']): disp1['forces'] = forces if is_compact_fc: p2s_map = self._phonon_primitive.p2s_map else: p2s_map = None if use_alm: from phonopy.interface.alm import get_fc2 as get_fc2_alm self._fc2 = get_fc2_alm(self._phonon_supercell, self._phonon_primitive, disp_dataset, atom_list=p2s_map, alm_options=alm_options, log_level=self._log_level) else: self._fc2 = get_fc2(self._phonon_supercell, self._phonon_supercell_symmetry, disp_dataset, atom_list=p2s_map) if symmetrize_fc2: if is_compact_fc: symmetrize_compact_force_constants( self._fc2, self._phonon_primitive) else: symmetrize_force_constants(self._fc2)
def symmetrize_force_constants(self, iteration=3): symmetrize_force_constants(self._force_constants, iteration) return self
def symmetrize_force_constants(self, iteration=3): symmetrize_force_constants(self._force_constants, iteration) self._set_dynamical_matrix()
def produce_fc3( self, forces_fc3=None, displacement_dataset=None, cutoff_distance=None, # set fc3 zero symmetrize_fc3r=False, is_compact_fc=False, fc_calculator=None, fc_calculator_options=None): """Calculate fc3 from displacements and forces Parameters ---------- forces_fc3 : Dummy argument displacement_dataset : dict Displacements in supercells. There are two types of formats. Type 1. Two atomic displacement in each supercell: {'natom': number of atoms in supercell, 'first_atoms': [ {'number': atom index of first displaced atom, 'displacement': displacement in Cartesian coordinates, 'forces': forces on atoms in supercell, 'second_atoms': [ {'number': atom index of second displaced atom, 'displacement': displacement in Cartesian coordinates}, 'forces': forces on atoms in supercell, ... ] }, ... ] } Type 2. All atomic displacements in each supercell: {'displacements': ndarray, dtype='double', order='C', shape=(supercells, atoms in supercell, 3) 'forces': ndarray, dtype='double',, order='C', shape=(supercells, atoms in supercell, 3)} In type 2, displacements and forces can be given by numpy array with different shape but that can be reshaped to (supercells, natom, 3). cutoff_distance : float After creating force constants, fc elements where any pair distance in atom triplets larger than cutoff_distance are set zero. symmetrize_fc3r : bool Only for type 1 displacement_dataset, translational and permutation symmetries are applied after creating fc3. This symmetrization is not very sophisticated and can break space group symmetry, but often useful. If better symmetrization is expected, it is recommended to use external force constants calculator such as ALM. Default is False. is_compact_fc : bool fc3 shape is False: (supercell, supercell, supecell, 3, 3, 3) True: (primitive, supercell, supecell, 3, 3, 3) where 'supercell' and 'primitive' indicate number of atoms in these cells. Default is False. fc_calculator : str or None Force constants calculator given by str. fc_calculator_options : dict Options for external force constants calculator. """ if displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = displacement_dataset if forces_fc3 is not None: self.forces = forces_fc3 msg = ("Forces have to be stored in disp_dataset as written in " "this method's docstring for the type1 dataset.") warnings.warn(msg, DeprecationWarning) if fc_calculator is not None: from phono3py.other.fc_calculator import ( get_fc3, get_displacements_and_forces_fc3) disps, forces = get_displacements_and_forces_fc3(disp_dataset) fc2, fc3 = get_fc3(self._supercell, self._primitive, disps, forces, fc_calculator=fc_calculator, fc_calculator_options=fc_calculator_options, is_compact_fc=is_compact_fc, log_level=self._log_level) else: fc2, fc3 = get_phono3py_fc3(self._supercell, self._primitive, disp_dataset, self._symmetry, is_compact_fc=is_compact_fc, verbose=self._log_level) if symmetrize_fc3r: if is_compact_fc: set_translational_invariance_compact_fc3( fc3, self._primitive) set_permutation_symmetry_compact_fc3(fc3, self._primitive) if self._fc2 is None: symmetrize_compact_force_constants( fc2, self._primitive) else: set_translational_invariance_fc3(fc3) set_permutation_symmetry_fc3(fc3) if self._fc2 is None: symmetrize_force_constants(fc2) # Set fc2 and fc3 self._fc3 = fc3 # Normally self._fc2 is overwritten in produce_fc2 if self._fc2 is None: self._fc2 = fc2
def produce_fc2(self, forces_fc2=None, displacement_dataset=None, symmetrize_fc2=False, is_compact_fc=False, fc_calculator=None, fc_calculator_options=None): """Calculate fc2 from displacements and forces Parameters ---------- forces_fc2 : Dummy argument displacement_dataset : dict Displacements in supercells. There are two types of formats. Type 1. Two atomic displacement in each supercell: {'natom': number of atoms in supercell, 'first_atoms': [ {'number': atom index of first displaced atom, 'displacement': displacement in Cartesian coordinates, 'forces': forces on atoms in supercell, 'second_atoms': [ {'number': atom index of second displaced atom, 'displacement': displacement in Cartesian coordinates}, 'forces': forces on atoms in supercell, ... ] }, ... ] } Type 2. All atomic displacements in each supercell: {'displacements': ndarray, dtype='double', order='C', shape=(supercells, atoms in supercell, 3) 'forces': ndarray, dtype='double',, order='C', shape=(supercells, atoms in supercell, 3)} In type 2, displacements and forces can be given by numpy array with different shape but that can be reshaped to (supercells, natom, 3). symmetrize_fc2 : bool Only for type 1 displacement_dataset, translational and permutation symmetries are applied after creating fc3. This symmetrization is not very sophisticated and can break space group symmetry, but often useful. If better symmetrization is expected, it is recommended to use external force constants calculator such as ALM. Default is False. is_compact_fc : bool fc2 shape is False: (supercell, supecell, 3, 3) True: (primitive, supecell, 3, 3) where 'supercell' and 'primitive' indicate number of atoms in these cells. Default is False. fc_calculator : str or None Force constants calculator given by str. fc_calculator_options : dict Options for external force constants calculator. """ if displacement_dataset is None: if self._phonon_displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = self._phonon_displacement_dataset else: disp_dataset = displacement_dataset if forces_fc2 is not None: self.phonon_forces = forces_fc2 msg = ("Forces have to be stored in disp_dataset as written in " "this method's docstring for the type1 dataset.") warnings.warn(msg, DeprecationWarning) if is_compact_fc: p2s_map = self._phonon_primitive.p2s_map else: p2s_map = None if fc_calculator is not None: disps, forces = get_displacements_and_forces(disp_dataset) self._fc2 = get_fc2(self._phonon_supercell, self._phonon_primitive, disps, forces, fc_calculator=fc_calculator, fc_calculator_options=fc_calculator_options, atom_list=p2s_map, log_level=self._log_level) else: self._fc2 = get_phonopy_fc2(self._phonon_supercell, self._phonon_supercell_symmetry, disp_dataset, atom_list=p2s_map) if symmetrize_fc2: if is_compact_fc: symmetrize_compact_force_constants(self._fc2, self._phonon_primitive) else: symmetrize_force_constants(self._fc2)
def symmetrize_force_constants(self): symmetrize_force_constants(self._force_constants) self._set_dynamical_matrix()
def create_phono3py_force_constants(phono3py, phonon_supercell_matrix, settings, force_to_eVperA=None, distance_to_A=None, compression=None, input_filename=None, output_filename=None, log_level=1): read_fc3 = settings.get_read_fc3() read_fc2 = settings.get_read_fc2() symmetrize_fc3r = (settings.get_is_symmetrize_fc3_r() or settings.get_fc_symmetry()) symmetrize_fc3q = settings.get_is_symmetrize_fc3_q() symmetrize_fc2 = (settings.get_is_symmetrize_fc2() or settings.get_fc_symmetry()) if settings.get_use_alm_fc2(): symmetrize_fc2 = False if settings.get_use_alm_fc3(): symmetrize_fc3r = False alm_options = None if settings.get_use_alm_fc3() or settings.get_use_alm_fc2(): if settings.get_alm_options() is not None: alm_option_types = {'solver': str, 'cutoff_distance': float} alm_options = {} for option_str in settings.get_alm_options().split(","): key, val = [x.strip() for x in option_str.split('=')[:2]] if key.lower() in alm_option_types: option_value = alm_option_types[key.lower()](val) alm_options[key.lower()] = option_value if log_level: show_phono3py_force_constants_settings(read_fc3, read_fc2, symmetrize_fc3r, symmetrize_fc3q, symmetrize_fc2, settings) # fc3 if (settings.get_is_joint_dos() or (settings.get_is_isotope() and not (settings.get_is_bterta() or settings.get_is_lbte())) or settings.get_read_gamma() or settings.get_read_pp() or settings.get_write_phonon() or settings.get_constant_averaged_pp_interaction() is not None): pass else: if read_fc3: # Read fc3.hdf5 if input_filename is None: filename = 'fc3.hdf5' else: filename = 'fc3.' + input_filename + '.hdf5' file_exists(filename, log_level) if log_level: print("Reading fc3 from %s" % filename) p2s_map = phono3py.get_primitive().get_primitive_to_supercell_map() try: fc3 = read_fc3_from_hdf5(filename=filename, p2s_map=p2s_map) except RuntimeError: import traceback traceback.print_exc() if log_level: print_error() sys.exit(1) num_atom = phono3py.get_supercell().get_number_of_atoms() if fc3.shape[1] != num_atom: print("Matrix shape of fc3 doesn't agree with supercell size.") if log_level: print_error() sys.exit(1) if symmetrize_fc3r: set_translational_invariance_fc3(fc3) set_permutation_symmetry_fc3(fc3) phono3py.set_fc3(fc3) else: # fc3 from FORCES_FC3 if not _create_phono3py_fc3(phono3py, force_to_eVperA, distance_to_A, symmetrize_fc3r, symmetrize_fc2, input_filename, output_filename, settings.get_is_compact_fc(), settings.get_use_alm_fc3(), alm_options, compression, log_level): print("fc3 was not created properly.") if log_level: print_error() sys.exit(1) cutoff_distance = settings.get_cutoff_fc3_distance() if cutoff_distance is not None and cutoff_distance > 0: if log_level: print("Cutting-off fc3 by zero (cut-off distance: %f)" % cutoff_distance) phono3py.cutoff_fc3_by_zero(cutoff_distance) if log_level: show_drift_fc3(phono3py.get_fc3(), primitive=phono3py.get_primitive()) # fc2 phonon_primitive = phono3py.get_phonon_primitive() phonon_supercell = phono3py.get_phonon_supercell() p2s_map = phonon_primitive.get_primitive_to_supercell_map() if read_fc2: if input_filename is None: filename = 'fc2.hdf5' else: filename = 'fc2.' + input_filename + '.hdf5' file_exists(filename, log_level) if log_level: print("Reading fc2 from %s" % filename) num_atom = phonon_supercell.get_number_of_atoms() try: phonon_fc2 = read_fc2_from_hdf5(filename=filename, p2s_map=p2s_map) except RuntimeError: import traceback traceback.print_exc() if log_level: print_error() sys.exit(1) if phonon_fc2.shape[1] != num_atom: print("Matrix shape of fc2 doesn't agree with supercell size.") if log_level: print_error() sys.exit(1) if symmetrize_fc2: if phonon_fc2.shape[0] == phonon_fc2.shape[1]: symmetrize_force_constants(phonon_fc2) else: symmetrize_compact_force_constants(phonon_fc2, phonon_primitive) phono3py.set_fc2(phonon_fc2) else: if phonon_supercell_matrix is None: if not _create_phono3py_fc2(phono3py, force_to_eVperA, distance_to_A, symmetrize_fc2, input_filename, settings.get_is_compact_fc(), settings.get_use_alm_fc2(), alm_options, log_level): print("fc2 was not created properly.") if log_level: print_error() sys.exit(1) else: if not _create_phono3py_phonon_fc2(phono3py, force_to_eVperA, distance_to_A, symmetrize_fc2, input_filename, settings.get_is_compact_fc(), settings.get_use_alm_fc2(), alm_options, log_level): print("fc2 was not created properly.") if log_level: print_error() sys.exit(1) if output_filename is None: filename = 'fc2.hdf5' else: filename = 'fc2.' + output_filename + '.hdf5' if log_level: print("Writing fc2 to %s" % filename) write_fc2_to_hdf5(phono3py.get_fc2(), filename=filename, p2s_map=p2s_map, compression=compression) if log_level: show_drift_force_constants(phono3py.get_fc2(), primitive=phonon_primitive, name='fc2')