예제 #1
0
def _read_phono3py_fc3(phono3py, symmetrize_fc3r, input_filename, log_level):
    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.primitive.p2s_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.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.fc3 = fc3
예제 #2
0
    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
예제 #3
0
 def set_permutation_symmetry(self):
     if self._fc2 is not None:
         set_permutation_symmetry(self._fc2)
     if self._fc3 is not None:
         set_permutation_symmetry_fc3(self._fc3)
예제 #4
0
    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 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')