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 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 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_fc3(supercell, primitive, disp_dataset, symmetry, is_compact_fc=False, verbose=False): # fc2 has to be full matrix to compute delta-fc2 # p2s_map elements are extracted if is_compact_fc=True at the last part. fc2 = get_fc2(supercell, symmetry, disp_dataset) fc3 = _get_fc3_least_atoms(supercell, primitive, disp_dataset, fc2, symmetry, is_compact_fc=is_compact_fc, verbose=verbose) if verbose: print("Expanding fc3") first_disp_atoms = np.unique( [x['number'] for x in disp_dataset['first_atoms']]) rotations = symmetry.get_symmetry_operations()['rotations'] lattice = supercell.get_cell().T permutations = symmetry.get_atomic_permutations() if is_compact_fc: s2p_map = primitive.get_supercell_to_primitive_map() p2s_map = primitive.get_primitive_to_supercell_map() p2p_map = primitive.get_primitive_to_primitive_map() s2compact = np.array([p2p_map[i] for i in s2p_map], dtype='intc') for i in first_disp_atoms: assert i in p2s_map target_atoms = [i for i in p2s_map if i not in first_disp_atoms] else: s2compact = np.arange(supercell.get_number_of_atoms(), dtype='intc') target_atoms = [i for i in s2compact if i not in first_disp_atoms] distribute_fc3(fc3, first_disp_atoms, target_atoms, lattice, rotations, permutations, s2compact, verbose=verbose) if 'cutoff_distance' in disp_dataset: if verbose: print("Cutting-off fc3 (cut-off distance: %f)" % disp_dataset['cutoff_distance']) if is_compact_fc: print("cutoff_fc3 doesn't support compact-fc3 yet.") raise ValueError cutoff_fc3(fc3, supercell, disp_dataset, symmetry, verbose=verbose) if is_compact_fc: p2s_map = primitive.get_primitive_to_supercell_map() fc2 = np.array(fc2[p2s_map], dtype='double', order='C') return fc2, fc3
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 _run_force_constants_from_forces(self, distributed_atom_list=None, decimals=None): if self._displacement_dataset is not None: self._force_constants = get_fc2( self._supercell, self._symmetry, self._displacement_dataset, atom_list=distributed_atom_list, decimals=decimals)
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 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 _run_force_constants_from_forces(self, distributed_atom_list=None, decimals=None, computation_algorithm="svd"): if self._displacement_dataset is not None: self._force_constants = get_fc2( self._supercell, self._symmetry, self._displacement_dataset, atom_list=distributed_atom_list, decimals=decimals, computation_algorithm=computation_algorithm)
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_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 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 get_fc3( supercell: PhonopyAtoms, primitive: Primitive, disp_dataset, symmetry: Symmetry, is_compact_fc=False, verbose=False, ): """Calculate fc3. Even when 'cutoff_distance' in dataset, all displacements are in the dataset, but force-sets out of cutoff-pair-distance are zero. fc3 is solved in exactly the same way. Then post-clean-up is performed. """ # fc2 has to be full matrix to compute delta-fc2 # p2s_map elements are extracted if is_compact_fc=True at the last part. fc2 = get_fc2(supercell, symmetry, disp_dataset) fc3 = _get_fc3_least_atoms( supercell, primitive, disp_dataset, fc2, symmetry, is_compact_fc=is_compact_fc, verbose=verbose, ) if verbose: print("Expanding fc3.") first_disp_atoms = np.unique( [x["number"] for x in disp_dataset["first_atoms"]]) rotations = symmetry.symmetry_operations["rotations"] lattice = supercell.cell.T permutations = symmetry.atomic_permutations if is_compact_fc: s2p_map = primitive.s2p_map p2s_map = primitive.p2s_map p2p_map = primitive.p2p_map s2compact = np.array([p2p_map[i] for i in s2p_map], dtype="int_") for i in first_disp_atoms: assert i in p2s_map target_atoms = [i for i in p2s_map if i not in first_disp_atoms] else: s2compact = np.arange(len(supercell), dtype="int_") target_atoms = [i for i in s2compact if i not in first_disp_atoms] distribute_fc3( fc3, first_disp_atoms, target_atoms, lattice, rotations, permutations, s2compact, verbose=verbose, ) if "cutoff_distance" in disp_dataset: if verbose: print("Cutting-off fc3 (cut-off distance: %f)" % disp_dataset["cutoff_distance"]) if is_compact_fc: print("cutoff_fc3 doesn't support compact-fc3 yet.") raise ValueError _cutoff_fc3_for_cutoff_pairs(fc3, supercell, disp_dataset, symmetry, verbose=verbose) if is_compact_fc: p2s_map = primitive.p2s_map fc2 = np.array(fc2[p2s_map], dtype="double", order="C") return fc2, fc3