示例#1
0
    def _get_supercell_phonon(self, ph_in):
        """Returns Phonopy instance of supercell as the primitive"""
        ph = Phonopy(ph_in.supercell,
                     supercell_matrix=[1, 1, 1],
                     primitive_matrix='P')
        fc_shape = ph_in.force_constants.shape
        if fc_shape[0] == fc_shape[1]:  # assume full fc
            ph.force_constants = ph_in.force_constants.copy()
        else:
            ph.force_constants = compact_fc_to_full_fc(ph_in,
                                                       ph_in.force_constants)

        if ph_in.nac_params:
            p2p = ph_in.primitive.p2p_map
            s2p = ph_in.primitive.s2p_map
            s2pp = [p2p[i] for i in s2p]
            born_in = ph_in.nac_params['born']
            born = [born_in[i] for i in s2pp]
            nac_params = {
                'born': np.array(born, dtype='double', order='C'),
                'factor': ph_in.nac_params['factor'],
                'dielectric': ph_in.nac_params['dielectric'].copy()
            }
            ph.nac_params = nac_params
        return ph
示例#2
0
    def _get_supercell_phonon(self, ph_in):
        """Return Phonopy instance of supercell as the primitive."""
        ph = Phonopy(ph_in.supercell,
                     supercell_matrix=[1, 1, 1],
                     primitive_matrix="P")
        fc_shape = ph_in.force_constants.shape
        if fc_shape[0] == fc_shape[1]:  # assume full fc
            ph.force_constants = ph_in.force_constants.copy()
        else:
            ph.force_constants = compact_fc_to_full_fc(ph_in,
                                                       ph_in.force_constants)

        if ph_in.nac_params:
            p2p = ph_in.primitive.p2p_map
            s2p = ph_in.primitive.s2p_map
            s2pp = [p2p[i] for i in s2p]
            born_in = ph_in.nac_params["born"]
            born = [born_in[i] for i in s2pp]
            nac_params = {
                "born": np.array(born, dtype="double", order="C"),
                "factor": ph_in.nac_params["factor"],
                "dielectric": ph_in.nac_params["dielectric"].copy(),
            }
            ph.nac_params = nac_params
        return ph
示例#3
0
def _get_phonon(ph_in):
    ph = Phonopy(ph_in.supercell, supercell_matrix=[1, 1, 1])
    ph.force_constants = ph_in.force_constants
    born_elems = {
        s: ph_in.nac_params['born'][i]
        for i, s in enumerate(ph_in.primitive.symbols)
    }
    born = [born_elems[s] for s in ph_in.supercell.symbols]
    epsilon = ph_in.nac_params['dielectric']
    factors = ph_in.nac_params['factor']
    ph.nac_params = {'born': born, 'factor': factors, 'dielectric': epsilon}
    return ph
示例#4
0
 def _phonons_allclose(self, ph, fc333):
     ph333 = Phonopy(ph.unitcell,
                     supercell_matrix=[3, 3, 3],
                     primitive_matrix=ph.primitive_matrix)
     ph333.force_constants = fc333
     ph333.nac_params = ph.nac_params
     comm_points = self._get_comm_points(ph)
     ph.run_qpoints(comm_points)
     ph333.run_qpoints(comm_points)
     np.testing.assert_allclose(ph.get_qpoints_dict()['frequencies'],
                                ph333.get_qpoints_dict()['frequencies'],
                                atol=1e-5)
示例#5
0
def _get_phonon(ph_in):
    ph = Phonopy(ph_in.supercell, supercell_matrix=[1, 1, 1])
    ph.force_constants = ph_in.force_constants
    born_elems = {
        s: ph_in.nac_params["born"][i]
        for i, s in enumerate(ph_in.primitive.symbols)
    }
    born = [born_elems[s] for s in ph_in.supercell.symbols]
    epsilon = ph_in.nac_params["dielectric"]
    factors = ph_in.nac_params["factor"]
    ph.nac_params = {"born": born, "factor": factors, "dielectric": epsilon}
    return ph
示例#6
0
    def to_phonopy(self) -> Phonopy:
        if self.force_constants is None:
            raise ValueError("Set force_constants first.")
        _nac = "" if self.nac_params else "*not* "
        logger.info(f"Parameters for a non-analytical term correction are "
                    f"{_nac}set.")

        result = Phonopy(unitcell=structure_to_phonopy_atoms(self.unitcell),
                         supercell_matrix=self.supercell_matrix,
                         nac_params=self.nac_params)
        result.force_constants = self.force_constants
        return result
示例#7
0
    def generate_displacements(self):
        label = 'force_constants_%d' % self.ctx.iteration
        fc_array = self.ctx[label].outputs.force_constants
        fc = fc_array.get_array('force_constants')
        phonon_setting_info = self.inputs.phonon_settings
        smat = phonon_setting_info['supercell_matrix']
        ph = Phonopy(phonopy_atoms_from_structure(self.inputs.structure),
                     supercell_matrix=smat,
                     primitive_matrix='auto')
        ph.force_constants = fc

        if 'random_seed' in self.inputs:
            random_seed = self.inputs.random_seed.value
        else:
            random_seed = None
        dataset = _generate_random_displacements(
            ph,
            self.inputs.number_of_snapshots.value,
            self.inputs.temperature.value,
            random_seed=random_seed)
        self.ctx.dataset = Dict(dict=dataset)
示例#8
0
文件: phonopy.py 项目: SMTG-UCL/sumo
def load_phonopy(
    filename,
    structure,
    dim,
    symprec=1e-5,
    primitive_matrix=None,
    factor=VaspToTHz,
    symmetrise=True,
    born=None,
    write_fc=False,
):
    """Load phonopy output and return an ``phonopy.Phonopy`` object.

    Args:
        filename (str): Path to phonopy output. Can be any of ``FORCE_SETS``,
            ``FORCE_CONSTANTS``, or ``force_constants.hdf5``.
        structure (:obj:`~pymatgen.core.structure.Structure`): The unitcell
            structure.
        dim (list): The supercell size, as a :obj:`list` of :obj:`float`.
        symprec (:obj:`float`, optional): The tolerance for determining the
            crystal symmetry.
        primitive_matrix (:obj:`list` or :obj:`str`, optional): The
            transformation matrix from the conventional to primitive cell. Only
            required when the conventional cell was used as the starting
            structure. Should be provided as a 3x3 :obj:`list` of :obj:`float`.
            Alternatively the str 'auto' may be provided.
        factor (:obj:`float`, optional): The conversion factor for phonon
            frequency. Defaults to :obj:`phonopy.units.VaspToTHz`.
        symmetrise (:obj:`bool`, optional): Symmetrise the force constants.
            Defaults to ``True``.
        born (:obj:`str`, optional): Path to file containing Born effective
            charges. Should be in the same format as the file produced by the
            ``phonopy-vasp-born`` script provided by phonopy.
        write_fc (:obj:`bool` or :obj:`str`,  optional): Write the force
            constants to disk. If ``True``, a ``FORCE_CONSTANTS`` file will be
            written. Alternatively, if set to ``"hdf5"``, a
            ``force_constants.hdf5`` file will be written. Defaults to
            ``False`` (force constants not written).
    """
    unitcell = get_phonopy_structure(structure)
    num_atom = unitcell.get_number_of_atoms()
    num_satom = determinant(dim) * num_atom

    phonon = Phonopy(unitcell,
                     dim,
                     primitive_matrix=primitive_matrix,
                     factor=factor,
                     symprec=symprec)

    if "FORCE_CONSTANTS" in filename or ".hdf5" in filename:
        # if force constants exist, use these to avoid recalculating them
        if ".hdf5" in filename:
            fc = file_IO.read_force_constants_hdf5(filename)

        elif "FORCE_CONSTANTS" in filename:
            fc = file_IO.parse_FORCE_CONSTANTS(filename=filename)

        if fc.shape[0] != num_satom:
            msg = ("\nNumber of atoms in supercell is not consistent with the "
                   "matrix shape of\nforce constants read from {}.\nPlease"
                   "carefully check --dim.")
            logging.error(msg.format(filename))
            sys.exit()
        phonon.force_constants = fc

    elif "FORCE_SETS" in filename:
        # load the force sets from file and calculate force constants
        fs = file_IO.parse_FORCE_SETS(filename=filename)

        if fs["natom"] != num_satom:
            msg = ("\nNumber of atoms in supercell is not consistent with the "
                   "the data in FORCE_SETS\nPlease carefully check --dim.")
            logging.error(msg.format(filename))
            sys.exit()

        phonon.dataset = fs

        logging.info("Calculating force constants...")
        phonon.produce_force_constants()

    if symmetrise:
        phonon.symmetrize_force_constants()

    if born:
        # load born parameters from a file
        nac_params = file_IO.parse_BORN(phonon._primitive,
                                        symprec=symprec,
                                        filename=born)
        # set the nac unit conversion factor manual,  specific to VASP
        nac_params["factor"] = Hartree * Bohr
        phonon.nac_params = nac_params

    if write_fc == "hdf5":
        file_IO.write_force_constants_to_hdf5(phonon.force_constants)
        logging.info("Force constants written to force_constants.hdf5.")

    elif write_fc:
        file_IO.write_FORCE_CONSTANTS(phonon.force_constants)
        logging.info("Force constants written to FORCE_CONSTANTS.")

    return phonon