def produce_fc2( self, forces_fc2, displacement_dataset=None, is_translational_symmetry=False, is_permutation_symmetry=False, translational_symmetry_type=None, ): if displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = displacement_dataset for forces, disp1 in zip(forces_fc2, disp_dataset["first_atoms"]): disp1["forces"] = forces self._fc2 = get_fc2(self._phonon_supercell, self._phonon_supercell_symmetry, disp_dataset) if is_permutation_symmetry: set_permutation_symmetry(self._fc2) if is_translational_symmetry: tsym_type = 1 else: tsym_type = 0 if translational_symmetry_type: tsym_type = translational_symmetry_type if tsym_type: set_translational_invariance(self._fc2, translational_symmetry_type=tsym_type)
def set_translational_invariance(self, translational_symmetry_type=1): if self._fc2 is not None: set_translational_invariance( self._fc2, translational_symmetry_type=translational_symmetry_type) if self._fc3 is not None: set_translational_invariance_fc3( self._fc3, translational_symmetry_type=translational_symmetry_type)
def produce_fc3( self, forces_fc3, displacement_dataset=None, cutoff_distance=None, # set fc3 zero is_translational_symmetry=False, is_permutation_symmetry=False, is_permutation_symmetry_fc2=False, translational_symmetry_type=None, ): if displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = displacement_dataset for forces, disp1 in zip(forces_fc3, disp_dataset["first_atoms"]): disp1["forces"] = forces fc2 = get_fc2(self._supercell, self._symmetry, disp_dataset) if is_permutation_symmetry_fc2: set_permutation_symmetry(fc2) if is_translational_symmetry: tsym_type = 1 else: tsym_type = 0 if translational_symmetry_type: tsym_type = translational_symmetry_type if tsym_type: set_translational_invariance(fc2, translational_symmetry_type=tsym_type) count = len(disp_dataset["first_atoms"]) for disp1 in disp_dataset["first_atoms"]: for disp2 in disp1["second_atoms"]: disp2["delta_forces"] = forces_fc3[count] - disp1["forces"] count += 1 self._fc3 = get_fc3( self._supercell, disp_dataset, fc2, self._symmetry, translational_symmetry_type=tsym_type, is_permutation_symmetry=is_permutation_symmetry, verbose=self._log_level, ) # Set fc3 elements zero beyond cutoff_distance if cutoff_distance: if self._log_level: print("Cutting-off fc3 by zero (cut-off distance: %f)" % cutoff_distance) self.cutoff_fc3_by_zero(cutoff_distance) # Set fc2 if self._fc2 is None: self._fc2 = fc2
def get_constrained_fc2( supercell, dataset_second_atoms, atom1, reduced_site_sym, translational_symmetry_type, is_permutation_symmetry, symprec, ): """ dataset_second_atoms: [{'number': 7, 'displacement': [], 'delta_forces': []}, ...] """ num_atom = supercell.get_number_of_atoms() fc2 = np.zeros((num_atom, num_atom, 3, 3), dtype="double") atom_list = np.unique([x["number"] for x in dataset_second_atoms]) for atom2 in atom_list: disps2 = [] sets_of_forces = [] for disps_second in dataset_second_atoms: if atom2 != disps_second["number"]: continue bond_sym = get_bond_symmetry(reduced_site_sym, supercell.get_scaled_positions(), atom1, atom2, symprec) disps2.append(disps_second["displacement"]) sets_of_forces.append(disps_second["delta_forces"]) solve_force_constants(fc2, atom2, disps2, sets_of_forces, supercell, bond_sym, symprec) # Shift positions according to set atom1 is at origin lattice = supercell.get_cell().T positions = supercell.get_scaled_positions() pos_center = positions[atom1].copy() positions -= pos_center distribute_force_constants( fc2, range(num_atom), atom_list, lattice, positions, np.array(reduced_site_sym, dtype="intc", order="C"), np.zeros((len(reduced_site_sym), 3), dtype="double"), symprec, ) if translational_symmetry_type: set_translational_invariance(fc2, translational_symmetry_type=translational_symmetry_type) if is_permutation_symmetry: set_permutation_symmetry(fc2) return fc2
def produce_fc4( self, forces_fc4, displacement_dataset, translational_symmetry_type=0, is_permutation_symmetry=False, is_permutation_symmetry_fc3=False, is_permutation_symmetry_fc2=False, ): disp_dataset = displacement_dataset file_count = 0 for disp1 in disp_dataset["first_atoms"]: disp1["forces"] = forces_fc4[file_count] file_count += 1 self._fc2 = get_fc2(self._supercell, self._symmetry, disp_dataset) if is_permutation_symmetry_fc2: set_permutation_symmetry(self._fc2) if translational_symmetry_type: set_translational_invariance(self._fc2, translational_symmetry_type=translational_symmetry_type) for disp1 in disp_dataset["first_atoms"]: for disp2 in disp1["second_atoms"]: disp2["forces"] = forces_fc4[file_count] disp2["delta_forces"] = disp2["forces"] - disp1["forces"] file_count += 1 self._fc3 = get_fc3( self._supercell, disp_dataset, self._fc2, self._symmetry, translational_symmetry_type=translational_symmetry_type, is_permutation_symmetry=is_permutation_symmetry_fc3, verbose=self._log_level, ) for disp1 in disp_dataset["first_atoms"]: for disp2 in disp1["second_atoms"]: for disp3 in disp2["third_atoms"]: disp3["delta_forces"] = forces_fc4[file_count] - disp2["forces"] file_count += 1 self._fc4 = get_fc4( self._supercell, disp_dataset, self._fc3, self._symmetry, translational_symmetry_type=translational_symmetry_type, is_permutation_symmetry=is_permutation_symmetry, verbose=self._log_level, )
def produce_fc2(self, forces_fc2, displacement_dataset=None, is_permutation_symmetry=False, is_translational_symmetry=False): if displacement_dataset is None: disp_dataset = self._displacement_dataset else: disp_dataset = displacement_dataset for forces, disp1 in zip(forces_fc2, disp_dataset['first_atoms']): disp1['forces'] = forces self._fc2 = get_fc2(self._phonon_supercell, self._phonon_supercell_symmetry, disp_dataset) if is_permutation_symmetry: set_permutation_symmetry(self._fc2) if is_translational_symmetry: set_translational_invariance(self._fc2)
def _get_fc3(self, forces_fc3, disp_dataset, cutoff_distance, is_translational_symmetry, is_permutation_symmetry, is_permutation_symmetry_fc2, translational_symmetry_type): for forces, disp1 in zip(forces_fc3, disp_dataset['first_atoms']): disp1['forces'] = forces fc2 = get_fc2(self._supercell, self._symmetry, disp_dataset) if is_permutation_symmetry_fc2: set_permutation_symmetry(fc2) if is_translational_symmetry: tsym_type = 1 else: tsym_type = 0 if translational_symmetry_type: tsym_type = translational_symmetry_type if tsym_type: set_translational_invariance(fc2, translational_symmetry_type=tsym_type) count = len(disp_dataset['first_atoms']) for disp1 in disp_dataset['first_atoms']: for disp2 in disp1['second_atoms']: disp2['delta_forces'] = forces_fc3[count] - disp1['forces'] count += 1 fc3 = get_fc3(self._supercell, disp_dataset, fc2, self._symmetry, translational_symmetry_type=tsym_type, is_permutation_symmetry=is_permutation_symmetry, verbose=self._log_level) # Set fc3 elements zero beyond cutoff_distance if cutoff_distance: if self._log_level: print("Cutting-off fc3 by zero (cut-off distance: %f)" % cutoff_distance) self.cutoff_fc3_by_zero(cutoff_distance, fc3=fc3) return fc2, fc3
def produce_fc2(self, forces_fc2, displacement_dataset=None, is_translational_symmetry=False, is_permutation_symmetry=False, translational_symmetry_type=None, 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 self._fc2 = get_fc2(self._phonon_supercell, self._phonon_supercell_symmetry, disp_dataset) if is_permutation_symmetry: set_permutation_symmetry(self._fc2) if is_translational_symmetry: tsym_type = 1 else: tsym_type = 0 if translational_symmetry_type: tsym_type = translational_symmetry_type if tsym_type: set_translational_invariance( self._fc2, translational_symmetry_type=tsym_type)
def get_constrained_fc2(supercell, dataset_second_atoms, atom1, reduced_site_sym, is_translational_symmetry, is_permutation_symmetry, symprec): """ dataset_second_atoms: [{'number': 7, 'displacement': [], 'delta_forces': []}, ...] """ num_atom = supercell.get_number_of_atoms() fc2 = np.zeros((num_atom, num_atom, 3, 3), dtype='double') atom_list = np.unique([x['number'] for x in dataset_second_atoms]) atom_list_done = [] for atom2 in atom_list: disps2 = [] sets_of_forces = [] for disps_second in dataset_second_atoms: if atom2 != disps_second['number']: continue atom_list_done.append(atom2) bond_sym = get_bond_symmetry( reduced_site_sym, supercell.get_scaled_positions(), atom1, atom2, symprec) disps2.append(disps_second['displacement']) sets_of_forces.append(disps_second['delta_forces']) solve_force_constants(fc2, atom2, disps2, sets_of_forces, supercell, bond_sym, symprec) # Shift positions according to set atom1 is at origin lattice = supercell.get_cell().T positions = supercell.get_scaled_positions() pos_center = positions[atom1].copy() positions -= pos_center atom_list = range(num_atom) distribute_force_constants(fc2, atom_list, atom_list_done, lattice, positions, np.intc(reduced_site_sym).copy(), np.zeros((len(reduced_site_sym), 3), dtype='double'), symprec) if is_translational_symmetry: set_translational_invariance(fc2) if is_permutation_symmetry: set_permutation_symmetry(fc2) return fc2
def set_translational_invariance(self): if self._fc2 is not None: set_translational_invariance(self._fc2) if self._fc3 is not None: set_translational_invariance_fc3(self._fc3)