Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
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
Exemplo n.º 5
0
    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,
        )
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
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
Exemplo n.º 10
0
 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)
Exemplo n.º 11
0
 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)