Пример #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)
Пример #2
0
    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)
Пример #3
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)
Пример #4
0
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
Пример #5
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)
Пример #6
0
 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)
Пример #7
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
Пример #8
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
Пример #9
0
 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)
Пример #10
0
 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)
Пример #11
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,
        )
Пример #12
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)
Пример #13
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)
Пример #14
0
    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)
Пример #15
0
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