Пример #1
0
def get_thermal_properties(structure, ph_settings, force_constants_list):
    from phonopy import Phonopy
    from aiida_phonopy.workchains.phonon import phonopy_bulk_from_structure

    free_energy_list = []
    entropy_list = []
    cv_list = []
    temperature = None
    for fc in force_constants_list:
        phonon = Phonopy(phonopy_bulk_from_structure(structure),
                         ph_settings.dict.supercell,
                         primitive_matrix=ph_settings.dict.primitive,
                         symprec=ph_settings.dict.symmetry_precision)

        # Normalization factor primitive to unit cell
        normalization_factor = phonon.unitcell.get_number_of_atoms()/phonon.primitive.get_number_of_atoms()

        phonon.set_force_constants(fc)
        phonon.set_mesh(ph_settings.dict.mesh, is_eigenvectors=True, is_mesh_symmetry=False)
        phonon.set_thermal_properties()
        temperature, free_energy, entropy, cv = phonon.get_thermal_properties()
        free_energy_list.append(np.array(free_energy) * normalization_factor)
        entropy_list.append(np.array(entropy) * normalization_factor)
        cv_list.append(np.array(cv) * normalization_factor)

    return np.array(free_energy_list), np.array(entropy_list).T, np.array(cv_list).T, temperature
Пример #2
0
def get_properties_from_phonopy(structure, phonopy_input, force_constants):
    """
    Calculate DOS and thermal properties using phonopy (locally)
    :param structure: Aiida StructureData Object
    :param phonopy_input: Aiida Parametersdata object containing a dictionary with the data needed to run phonopy:
            supercells matrix, primitive matrix and q-points mesh.
    :param force_constants:
    :return:
    """

    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy import Phonopy

    # Generate phonopy phonon object
    bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                        positions=[site.position for site in structure.sites],
                        cell=structure.cell)

    phonopy_input = phonopy_input.get_dict()
    force_constants = force_constants.get_array('force_constants')

    phonon = Phonopy(bulk,
                     phonopy_input['supercell'],
                     primitive_matrix=phonopy_input['primitive'])

    phonon.set_force_constants(force_constants)

    #Normalization factor primitive to unit cell
    normalization_factor = phonon.unitcell.get_number_of_atoms(
    ) / phonon.primitive.get_number_of_atoms()

    phonon.set_mesh(phonopy_input['mesh'],
                    is_eigenvectors=True,
                    is_mesh_symmetry=False)
    phonon.set_total_DOS()
    phonon.set_partial_DOS()

    # get DOS (normalized to unit cell)
    total_dos = phonon.get_total_DOS() * normalization_factor
    partial_dos = phonon.get_partial_DOS() * normalization_factor

    # Stores DOS data in DB as a workflow result
    dos = ArrayData()
    dos.set_array('frequency', total_dos[0])
    dos.set_array('total_dos', total_dos[1])
    dos.set_array('partial_dos', partial_dos[1])

    #THERMAL PROPERTIES (per primtive cell)
    phonon.set_thermal_properties()
    t, free_energy, entropy, cv = phonon.get_thermal_properties()

    # Stores thermal properties (per unit cell) data in DB as a workflow result
    thermal_properties = ArrayData()
    thermal_properties.set_array('temperature', t)
    thermal_properties.set_array('free_energy',
                                 free_energy * normalization_factor)
    thermal_properties.set_array('entropy', entropy * normalization_factor)
    thermal_properties.set_array('cv', cv * normalization_factor)

    return {'thermal_properties': thermal_properties, 'dos': dos}
def phonopy_calculation_inline(**kwargs):
    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy import Phonopy

    structure = kwargs.pop('structure')
    phonopy_input = kwargs.pop('phonopy_input').get_dict()
    force_constants = kwargs.pop('force_constants').get_array(
        'force_constants')

    # Generate phonopy phonon object
    bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                        positions=[site.position for site in structure.sites],
                        cell=structure.cell)

    phonon = Phonopy(bulk,
                     phonopy_input['supercell'],
                     primitive_matrix=phonopy_input['primitive'],
                     distance=phonopy_input['distance'])

    phonon.set_force_constants(force_constants)

    # Normalization factor primitive to unit cell
    normalization_factor = phonon.unitcell.get_number_of_atoms(
    ) / phonon.primitive.get_number_of_atoms()

    phonon.set_mesh(phonopy_input['mesh'],
                    is_eigenvectors=True,
                    is_mesh_symmetry=False)
    phonon.set_total_DOS()
    phonon.set_partial_DOS()

    # get DOS (normalized to unit cell)
    total_dos = phonon.get_total_DOS() * normalization_factor
    partial_dos = phonon.get_partial_DOS() * normalization_factor

    # Stores DOS data in DB as a workflow result
    dos = ArrayData()
    dos.set_array('frequency', total_dos[0])
    dos.set_array('total_dos', total_dos[1])
    dos.set_array('partial_dos', partial_dos[1])

    # THERMAL PROPERTIES (per primtive cell)
    phonon.set_thermal_properties()
    t, free_energy, entropy, cv = phonon.get_thermal_properties()

    # Stores thermal properties (per unit cell) data in DB as a workflow result
    thermal_properties = ArrayData()
    thermal_properties.set_array('temperature', t)
    thermal_properties.set_array('free_energy',
                                 free_energy * normalization_factor)
    thermal_properties.set_array('entropy', entropy * normalization_factor)
    thermal_properties.set_array('cv', cv * normalization_factor)

    return {'thermal_properties': thermal_properties, 'dos': dos}
Пример #4
0
def get_f_vib_phonopy(
        structure,
        supercell_matrix,
        vasprun_path,
        qpoint_mesh=(50, 50, 50),
        t_min=5,
        t_step=5,
        t_max=2000.0,
):
    """
    Return F_vib(T) for the unitcell in eV/atom

    Parameters
    ----------
    structure : pymatgen.Structure
        Unitcell (not supercell) of interest.
    supercell_matrix : numpy.ndarray
        3x3 matrix of the supercell deformation, e.g. [[3, 0, 0], [0, 3, 0], [0, 0, 3]].
    vasprun_path : str
        String pointing to a vasprun.xml file from a force constants run
    qpoint_mesh : list
        Mesh of q-points to calculate thermal properties on.
    t_min : float
        Minimum temperature
    t_step : float
        Temperature step size
    t_max : float
        Maximum temperature (inclusive)

    Returns
    -------
    tuple
        Tuple of (temperature, F_vib, S_vib, Cv_vib, force_constants)

    """
    # get the force constants from a vasprun.xml file
    vasprun = PhonopyVasprun(vasprun_path)
    force_constants, elements = vasprun.read_force_constants()

    ph_unitcell = get_phonopy_structure(structure)
    ph = Phonopy(ph_unitcell, supercell_matrix)
    # set the force constants we found
    ph.set_force_constants(force_constants)
    # calculate the thermal properties
    ph.set_mesh(qpoint_mesh)
    ph.set_thermal_properties(t_min=t_min, t_max=t_max, t_step=t_step)
    # the thermal properties are for the unit cell
    temperatures, f_vib, s_vib, cv_vib = ph.get_thermal_properties()
    # convert the units into our expected eV/atom-form (and per K)
    f_vib *= J_per_mol_to_eV_per_atom * 1000
    s_vib *= J_per_mol_to_eV_per_atom
    cv_vib *= J_per_mol_to_eV_per_atom
    return temperatures, f_vib, s_vib, cv_vib, ph.force_constants
Пример #5
0
def get_phonopy_qha(energies, volumes, force_constants, structure, t_min, t_step, t_max, mesh, eos,
                      pressure=0):
    """
    Return phonopy QHA interface.

    Args:
        energies (list):
        volumes (list):
        force_constants (list):
        structure (Structure):
        t_min (float): min temperature
        t_step (float): temperature step
        t_max (float): max temperature
        mesh (list/tuple): reciprocal space density
        eos (str): equation of state used for fitting the energies and the volumes.
            options supported by phonopy: vinet, murnaghan, birch_murnaghan
        pressure (float): in GPa, optional.

    Returns:
        PhonopyQHA
    """
    from phonopy import Phonopy
    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy import PhonopyQHA
    from phonopy.units import EVAngstromToGPa

    phon_atoms = PhonopyAtoms(symbols=[str(s.specie) for s in structure],
                              scaled_positions=structure.frac_coords,
                              cell=structure.lattice.matrix)
    scell = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    phonon = Phonopy(phon_atoms, scell)
    # compute the required phonon thermal properties
    temperatures = []
    free_energy = []
    entropy = []
    cv = []
    for f in force_constants:
        phonon.set_force_constants(-np.array(f))
        phonon.set_mesh(list(mesh))
        phonon.set_thermal_properties(t_step=t_step, t_min=t_min, t_max=t_max)
        t, g, e, c = phonon.get_thermal_properties()
        temperatures.append(t)
        free_energy.append(g)
        entropy.append(e)
        cv.append(c)

    # add pressure contribution
    energies = np.array(energies) + np.array(volumes) * pressure / EVAngstromToGPa
    # quasi-harmonic approx
    return PhonopyQHA(volumes, energies, eos=eos, temperatures=temperatures[0],
                      free_energy=np.array(free_energy).T, cv=np.array(cv).T,
                      entropy=np.array(entropy).T, t_max=np.max(temperatures[0]))
Пример #6
0
for q, d, freq in zip(q_points, distances, frequencies):
    print q, d, freq
phonon.plot_band_structure().show()

# Mesh sampling 20x20x20
phonon.set_mesh([20, 20, 20])
phonon.set_thermal_properties(t_step=10,
                              t_max=1000,
                              t_min=0)

# DOS
phonon.set_total_DOS(sigma=0.1)
for omega, dos in np.array(phonon.get_total_DOS()).T:
    print "%15.7f%15.7f" % (omega, dos)
phonon.plot_total_DOS().show()

# Thermal properties
for t, free_energy, entropy, cv in np.array(phonon.get_thermal_properties()).T:
    print ("%12.3f " + "%15.7f" * 3) % ( t, free_energy, entropy, cv )
phonon.plot_thermal_properties().show()

# PDOS
phonon.set_mesh([10, 10, 10],
                is_mesh_symmetry=False,
                is_eigenvectors=True)
phonon.set_partial_DOS(tetrahedron_method=True)
omegas, pdos = phonon.get_partial_DOS()
pdos_indices = [[0], [1]]
phonon.plot_partial_DOS(pdos_indices=pdos_indices,
                        legend=pdos_indices).show()
Пример #7
0
append_band(bands, [0.5, 0.0, 0.0], [0.5, 0.5, 0.0])
append_band(bands, [0.5, 0.5, 0.0], [0.0, 0.0, 0.0])
append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.5, 0.5])
phonon.set_band_structure(bands)
q_points, distances, frequencies, eigvecs = phonon.get_band_structure()
for q, d, freq in zip(q_points, distances, frequencies):
    print q, d, freq
phonon.plot_band_structure().show()

# Mesh sampling 20x20x20
phonon.set_mesh([20, 20, 20])
phonon.set_thermal_properties(t_step=10, t_max=1000, t_min=0)

# DOS
phonon.set_total_DOS(sigma=0.1)
for omega, dos in np.array(phonon.get_total_DOS()).T:
    print "%15.7f%15.7f" % (omega, dos)
phonon.plot_total_DOS().show()

# Thermal properties
for t, free_energy, entropy, cv in np.array(phonon.get_thermal_properties()).T:
    print("%12.3f " + "%15.7f" * 3) % (t, free_energy, entropy, cv)
phonon.plot_thermal_properties().show()

# PDOS
phonon.set_mesh([10, 10, 10], is_mesh_symmetry=False, is_eigenvectors=True)
phonon.set_partial_DOS(tetrahedron_method=True)
omegas, pdos = phonon.get_partial_DOS()
pdos_indices = [[0], [1]]
phonon.plot_partial_DOS(pdos_indices=pdos_indices, legend=pdos_indices).show()
Пример #8
0
def phonopy_calculation_inline(**kwargs):
    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy import Phonopy

    structure = kwargs.pop('structure')
    phonopy_input = kwargs.pop('phonopy_input').get_dict()
    force_constants = kwargs.pop('force_constants').get_array(
        'force_constants')
    bands = get_path_using_seekpath(structure)

    # Generate phonopy phonon object
    bulk = PhonopyAtoms(symbols=[site.kind_name for site in structure.sites],
                        positions=[site.position for site in structure.sites],
                        cell=structure.cell)

    phonon = Phonopy(bulk,
                     phonopy_input['supercell'],
                     primitive_matrix=phonopy_input['primitive'],
                     symprec=phonopy_input['symmetry_precision'])

    phonon.set_force_constants(force_constants)

    try:
        print('trying born')
        nac_data = kwargs.pop('nac_data')
        born = nac_data.get_array('born_charges')
        epsilon = nac_data.get_array('epsilon')

        phonon.set_nac_params(get_born_parameters(phonon, born, epsilon))
        print('born succeed')
    except:
        pass

    # Normalization factor primitive to unit cell
    norm_primitive_to_unitcell = phonon.unitcell.get_number_of_atoms(
    ) / phonon.primitive.get_number_of_atoms()

    phonon.set_band_structure(bands['ranges'])

    phonon.set_mesh(phonopy_input['mesh'],
                    is_eigenvectors=True,
                    is_mesh_symmetry=False)
    phonon.set_total_DOS(tetrahedron_method=True)
    phonon.set_partial_DOS(tetrahedron_method=True)

    # get band structure
    band_structure_phonopy = phonon.get_band_structure()
    q_points = np.array(band_structure_phonopy[0])
    q_path = np.array(band_structure_phonopy[1])
    frequencies = np.array(band_structure_phonopy[2])
    band_labels = np.array(bands['labels'])

    # stores band structure
    band_structure = ArrayData()
    band_structure.set_array('q_points', q_points)
    band_structure.set_array('q_path', q_path)
    band_structure.set_array('frequencies', frequencies)
    band_structure.set_array('labels', band_labels)

    # get DOS (normalized to unit cell)
    total_dos = phonon.get_total_DOS() * norm_primitive_to_unitcell
    partial_dos = phonon.get_partial_DOS() * norm_primitive_to_unitcell

    # Stores DOS data in DB as a workflow result
    dos = ArrayData()
    dos.set_array('frequency', total_dos[0])
    dos.set_array('total_dos', total_dos[1] * norm_primitive_to_unitcell)
    dos.set_array('partial_dos', partial_dos[1] * norm_primitive_to_unitcell)
    dos.set_array('partial_symbols', np.array(phonon.primitive.symbols))

    # THERMAL PROPERTIES (per primtive cell)
    phonon.set_thermal_properties()
    t, free_energy, entropy, cv = phonon.get_thermal_properties()

    # Stores thermal properties (per mol) data in DB as a workflow result
    thermal_properties = ArrayData()
    thermal_properties.set_array('temperature', t)
    thermal_properties.set_array('free_energy',
                                 free_energy * norm_primitive_to_unitcell)
    thermal_properties.set_array('entropy',
                                 entropy * norm_primitive_to_unitcell)
    thermal_properties.set_array('cv', cv * norm_primitive_to_unitcell)

    return {
        'thermal_properties': thermal_properties,
        'dos': dos,
        'band_structure': band_structure
    }
Пример #9
0
class PhonopyJob(AtomisticParallelMaster):
    """

    Args:
        project:
        job_name:
    """
    def __init__(self, project, job_name):
        super(PhonopyJob, self).__init__(project, job_name)
        self.__name__ = "PhonopyJob"
        self.__version__ = "0.0.1"
        self.input["interaction_range"] = (10.0,
                                           "Minimal size of supercell, Ang")
        self.input["factor"] = (
            VaspToTHz,
            "Frequency unit conversion factor (default for VASP)",
        )
        self.input["displacement"] = (0.01, "atoms displacement, Ang")
        self.input["dos_mesh"] = (20, "mesh size for DOS calculation")

        self.phonopy = None
        self._job_generator = PhonopyJobGenerator(self)
        self._disable_phonopy_pickle = False
        s.publication_add(phonopy_publication())

    @property
    def phonopy_pickling_disabled(self):
        return self._disable_phonopy_pickle

    @phonopy_pickling_disabled.setter
    def phonopy_pickling_disabled(self, disable):
        self._disable_phonopy_pickle = disable

    @property
    def _phonopy_unit_cell(self):
        if self.structure is not None:
            return atoms_to_phonopy(self.structure)
        else:
            return None

    def _enable_phonopy(self):
        if self.phonopy is None:
            if self.structure is not None:
                self.phonopy = Phonopy(
                    unitcell=self._phonopy_unit_cell,
                    supercell_matrix=self._phonopy_supercell_matrix(),
                    factor=self.input["factor"],
                )
                self.phonopy.generate_displacements(
                    distance=self.input["displacement"])
                self.to_hdf()
            else:
                raise ValueError(
                    "No reference job/ No reference structure found.")

    def list_structures(self):
        if self.structure is not None:
            self._enable_phonopy()
            return [struct for _, struct in self._job_generator.parameter_list]
        else:
            return []

    def _phonopy_supercell_matrix(self):
        if self.structure is not None:
            supercell_range = np.ceil(
                self.input["interaction_range"] / np.array([
                    np.linalg.norm(vec)
                    for vec in self._phonopy_unit_cell.get_cell()
                ]))
            return np.eye(3) * supercell_range
        else:
            return np.eye(3)

    def run_static(self):
        # Initialise the phonopy object before starting the first calculation.
        self._enable_phonopy()
        super(PhonopyJob, self).run_static()

    def run_if_interactive(self):
        self._enable_phonopy()
        super(PhonopyJob, self).run_if_interactive()

    def to_hdf(self, hdf=None, group_name=None):
        """
        Store the PhonopyJob in an HDF5 file

        Args:
            hdf (ProjectHDFio): HDF5 group object - optional
            group_name (str): HDF5 subgroup name - optional
        """
        super(PhonopyJob, self).to_hdf(hdf=hdf, group_name=group_name)
        if self.phonopy is not None and not self._disable_phonopy_pickle:
            with self.project_hdf5.open("output") as hdf5_output:
                hdf5_output["phonopy_pickeled"] = codecs.encode(
                    pickle.dumps(self.phonopy), "base64").decode()

    def from_hdf(self, hdf=None, group_name=None):
        """
        Restore the PhonopyJob from an HDF5 file

        Args:
            hdf (ProjectHDFio): HDF5 group object - optional
            group_name (str): HDF5 subgroup name - optional
        """
        super(PhonopyJob, self).from_hdf(hdf=hdf, group_name=group_name)
        with self.project_hdf5.open("output") as hdf5_output:
            if "phonopy_pickeled" in hdf5_output.list_nodes():
                self.phonopy = pickle.loads(
                    codecs.decode(hdf5_output["phonopy_pickeled"].encode(),
                                  "base64"))
                if "dos_total" in hdf5_output.list_nodes():
                    self._dos_total = hdf5_output["dos_total"]
                if "dos_energies" in hdf5_output.list_nodes():
                    self._dos_energies = hdf5_output["dos_energies"]

    def collect_output(self):
        """

        Returns:

        """
        if self.server.run_mode.interactive:
            forces_lst = self.project_hdf5.inspect(
                self.child_ids[0])["output/generic/forces"]
        else:
            forces_lst = [
                self.project_hdf5.inspect(job_id)["output/generic/forces"][-1]
                for job_id in self._get_jobs_sorted()
            ]
        self.phonopy.set_forces(forces_lst)
        self.phonopy.produce_force_constants()
        self.phonopy.set_mesh(mesh=[self.input["dos_mesh"]] * 3)
        qpoints, weights, frequencies, eigvecs = self.phonopy.get_mesh()
        self.phonopy.set_total_DOS()
        erg, dos = self.phonopy.get_total_DOS()

        self.to_hdf()

        with self.project_hdf5.open("output") as hdf5_out:
            hdf5_out["dos_total"] = dos
            hdf5_out["dos_energies"] = erg
            hdf5_out["qpoints"] = qpoints
            hdf5_out["supercell_matrix"] = self._phonopy_supercell_matrix()
            hdf5_out[
                "displacement_dataset"] = self.phonopy.get_displacement_dataset(
                )
            hdf5_out[
                "dynamical_matrix"] = self.phonopy.dynamical_matrix.get_dynamical_matrix(
                )
            hdf5_out["force_constants"] = self.phonopy.force_constants

    def write_phonopy_force_constants(self,
                                      file_name="FORCE_CONSTANTS",
                                      cwd=None):
        """

        Args:
            file_name:
            cwd:

        Returns:

        """
        if cwd is not None:
            file_name = posixpath.join(cwd, file_name)
        write_FORCE_CONSTANTS(force_constants=self.phonopy.force_constants,
                              filename=file_name)

    def get_hesse_matrix(self):
        """

        Returns:

        """
        unit_conversion = (
            scipy.constants.physical_constants["Hartree energy in eV"][0] /
            scipy.constants.physical_constants["Bohr radius"][0]**2 *
            scipy.constants.angstrom**2)
        force_shape = np.shape(self.phonopy.force_constants)
        force_reshape = force_shape[0] * force_shape[2]
        return (np.transpose(self.phonopy.force_constants,
                             (0, 2, 1, 3)).reshape(
                                 (force_reshape, force_reshape)) /
                unit_conversion)

    def get_thermal_properties(self,
                               t_min=1,
                               t_max=1500,
                               t_step=50,
                               temperatures=None):
        """

        Args:
            t_min:
            t_max:
            t_step:
            temperatures:

        Returns:

        """
        self.phonopy.set_thermal_properties(t_step=t_step,
                                            t_max=t_max,
                                            t_min=t_min,
                                            temperatures=temperatures)
        return thermal(*self.phonopy.get_thermal_properties())

    @property
    def dos_total(self):
        """

        Returns:

        """
        return self["output/dos_total"]

    @property
    def dos_energies(self):
        """

        Returns:

        """
        return self["output/dos_energies"]

    @property
    def dynamical_matrix(self):
        """

        Returns:

        """
        return np.real_if_close(
            self.phonopy.get_dynamical_matrix().get_dynamical_matrix())

    def dynamical_matrix_at_q(self, q):
        """

        Args:
            q:

        Returns:

        """
        return np.real_if_close(self.phonopy.get_dynamical_matrix_at_q(q))

    def plot_dos(self, ax=None, *args, **qwargs):
        """

        Args:
            *args:
            ax:
            **qwargs:

        Returns:

        """
        try:
            import pylab as plt
        except ImportError:
            import matplotlib.pyplot as plt
        if ax is None:
            fig, ax = plt.subplots(1, 1)
        ax.plot(self["output/dos_energies"], self["output/dos_total"], *args,
                **qwargs)
        ax.set_xlabel("Frequency [THz]")
        ax.set_ylabel("DOS")
        ax.set_title("Phonon DOS vs Energy")
        return ax
Пример #10
0
 def __init__(self, numbatom=125, supercell=5):
     
     #species = 'WRe_0.25_conv'
     species = 'WRe_0.00'
     #species = 'Re'
     ###read force constants from vasprun.xml###
     vasprun = etree.iterparse('vasprun.xml', tag='varray')
     #fc = vasp.get_force_constants_vasprun_xml(vasprun,1) #pass xml input and species atomic weight.
     ###########################################
     
     ########### read positionsl ###############
     primitive = vasp.get_atoms_from_poscar(open('POSCAR-p'),'W')
     superc =  vasp.get_atoms_from_poscar(open('POSCAR'),'W')
     ###########################################
     numbatom =  superc.get_number_of_atoms()
     #print primitive.get_cell()
     #print primitive.get_scaled_positions()
     #print superc.get_scaled_positions()
     
     print numbatom, species, os.getcwd()
     if species=='W':
     #Tungsten
         fc = vasp.get_force_constants_vasprun_xml(vasprun,1,0,64)
         s = 4.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
         
     elif species=='W_conv_2x2x2':
     #Tungsten
         fc = vasp.get_force_constants_vasprun_xml(vasprun,1,2)
         s = 2.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W','W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     
     elif species=='W_conv':
     #Tungsten
         fc = vasp.get_force_constants_vasprun_xml(vasprun,1,2)
         s = 4.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W','W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     
     elif species=='WRe_0.25_conv':
     #Tungsten
         fc = vasp.get_force_constants_vasprun_xml(vasprun,8,2,64)
         s = 4.
         a = superc.get_cell()[0][0]*2.
         print a, primitive.get_scaled_positions()
         bulk = PhonopyAtoms(symbols=['W','W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         #print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     
     elif species == 'WRe_B2': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,1,1)
         s = 5.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W','Re'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     elif species == 'WRe_0.00': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,1,0,numbatom)
         s = supercell
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [200, 200, 200]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     elif species == 'WRe_0.03': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,2,0)
         s = 2.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     elif species == 'WRe_0.06': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,3,0)
         s = 2.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     
     elif species == 'WRe_0.09': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,4,0)
         s = 2.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     elif species == 'WRe_0.12': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,5,0)
         s = 2.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     
     elif species == 'WRe_0.18': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,6,0)
         s = 2.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)
     elif species == 'WRe_0.25': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,7,0)
         s = 2.
         a = primitive.get_cell()[0][0]*2.
         print a, primitive.get_scaled_positions()
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         #phonon.set_partial_DOS()
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)    
     
     elif species == 'WRe_0.50': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,8,0)
         s = 2.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['W'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         #print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         #print frequencies
         phonon.set_total_DOS()
         #phonon.set_partial_DOS()
         phonon.set_thermal_properties(t_step=10,
                                       t_max=3700,
                                       t_min=0)    
         
         
     elif species == 'Au': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,1,0)
         #Gold
         s = 5.
         a = superc.get_cell()[0][0]
         bulk = PhonopyAtoms(symbols=['Au'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[0.5, 0.5, 0.0],[0.0, 0.5, 0.5],[0.5, 0.0, 0.5]],
                          distance=0.01, factor=15.633302)
         
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         phonon.set_partial_DOS()
         phonon.set_thermal_properties(t_step=10,
                                       t_max=1300,
                                       t_min=0)
     
     elif species == 'Mo': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,10,0)
         s = 5.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['Mo'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=2500,
                                       t_min=0)
     
     
     elif species == 'Re': 
         fc = vasp.get_force_constants_vasprun_xml(vasprun,9,0)
         s = 5.
         a = superc.get_cell()[0][0]*2.
         print a
         bulk = PhonopyAtoms(symbols=['Re'] * 1,
                             scaled_positions= primitive.get_scaled_positions())
         bulk.set_cell(np.diag((a, a, a)))
         phonon = Phonopy(bulk,
                          [[s,0.,0.],[0.,s,0.],[0.,0.,s]],
                          primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]],
                          distance=0.01, factor=15.633302)
         print fc
         phonon.set_force_constants(fc[0])
         phonon.set_dynamical_matrix()
         #print phonon.get_dynamical_matrix_at_q([0,0,0])
         mesh = [100, 100, 100]
         phonon.set_mesh(mesh)
         qpoints, weights, frequencies, eigvecs = phonon.get_mesh()
         print frequencies
         phonon.set_total_DOS()
         
         phonon.set_thermal_properties(t_step=10,
                                       t_max=2500,
                                       t_min=0)
     
     
     f = open('F_TV','w')
     for t, free_energy, entropy, cv in np.array(phonon.get_thermal_properties()).T:
         #print t, cv
         #print ("%12.3f " + "%15.7f" * 3) % ( t, free_energy, entropy, cv )
         f.write(("%12.3f " + "%15.7f" + "\n") % ( t, free_energy))
     f.close()
     
     fc = open('thermal_properties','w')
     for t, free_energy, entropy, cv in np.array(phonon.get_thermal_properties()).T:
         fc.write(("%12.3f " + "%15.7f" *3 + "\n") % ( t, free_energy, entropy, cv ))
     fc.close()
     
     #phonon.plot_thermal_properties().show()
     
     #phonon.plot_total_DOS().show()
     phonon.write_total_DOS()
     #phonon.write_partial_DOS()
     phonon.write_yaml_thermal_properties()
     
     bands = []
     
     #### PRIMITIVE
     
     q_start  = np.array([0.0, 0.0, 0.0])
     #q_start  = np.array([0.5, 0.5, 0.0])
     q_end    = np.array([-0.5, 0.5, 0.5])
     #q_end    = np.array([0., 0., 0.])
     band = []
     for i in range(101):
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     
     band = []
     
     
     q_start  = np.array([-0.5, 0.5, 0.5])
     #q_start  = np.array([0., 0., 0.])
     q_end    = np.array([0.25, 0.25, 0.25])
     #q_end    = np.array([1., 0., 0.])
     
     for i in range(101):
         #band.append([-0.5+3*1/400*i, 0.5-1/400*i, 0.5-1/400*i])
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     #print band
     q_start  = np.array([0.25, 0.25, 0.25])
     q_end    = np.array([0., 0., 0.])
     band = []
     for i in range(101):
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     
     q_start  = np.array([0., 0., 0.])
     q_end    = np.array([0.0, 0., 0.5])
     band = []
     for i in range(101):
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     
     #q_start  = np.array([0.0, 0.0, 0.0])
     #q_end    = np.array([0.5, 0.5, 0.5])
     #band = []
     #for i in range(101):
     #    band.append(q_start + (q_end - q_start) / 100 * i)
     #bands.append(band)
     
     """
     ###### CONVENTIONAL CELL ######
     q_start  = np.array([0.0, 0.0, 0.0])
     q_end    = np.array([-0.5, 0.5, 0.5])
     band = []
     for i in range(101):
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     
     
     q_start  = np.array([-0.5, 0.5, 0.5])
     q_end    = np.array([1./4., 1./4., 1./4.])
     band = []
     for i in range(101):
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     q_start  = np.array([1./4., 1./4., 1./4.])
     q_end    = np.array([0.0, 0.0, 0.0])
     band = []
     for i in range(101):
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     q_start  = np.array([0.0, 0.0, 0.0])
     q_end    = np.array([0.5, 0.0, 0.0])
     band = []
     for i in range(101):
         band.append(q_start + (q_end - q_start) / 100 * i)
     bands.append(band)
     """
     phonon.set_band_structure(bands)
     #phonon.plot_band_structure().show()
     
     q_points, distances, frequencies, eigvecs = phonon.get_band_structure()
     disp = {'q':q_points, 'distances':distances, 'frequencies':frequencies, 'eigvecs':eigvecs}
     f = open('ph_dispersion.pkl','w')
     pickle.dump(disp, f)
     f.close()
Пример #11
0
print "%12s %15s%15s%15s" % ('T [K]',
                              'F [kJ/mol]',
                              'S [J/K/mol]',
                              'C_v [J/K/mol]')

# get_thermal_properties returns numpy array of
#
# [[ temperature, free energy, entropy, heat capacity ],
#  [ temperature, free energy, entropy, heat capacity ],...,]
#
# Frequency has to be given in THz internally. Therefore unit
# conversion factor may be specified when calling Phonon class. The
# unit of frequency in a calculator is square root of the unit of
# dynamical matrix, i.e.,
#
# /      [energy]       \^(1/2)
# | ------------------- |
# \ [mass] [distance]^2 /
#
# THz is the value above divided by 2pi*1e12 (2pi comes from the
# factor between angular frequency and ordinary frequency). See
# units.py in the phonopy directory.
phonon.set_mesh( mesh, shift )
phonon.set_thermal_properties( t_step=10,
                               t_max=1000,
                               t_min=0 )
for t, free_energy, entropy, cv in phonon.get_thermal_properties():
    print ("%12.3f " + "%15.7f" * 3) % ( t, free_energy, entropy, cv )

phonon.plot_thermal_properties().show()
Пример #12
0
def get_properties_from_phonopy(**kwargs):
    """
    Calculate DOS and thermal properties using phonopy (locally)
    :param structure: StructureData Object
    :param ph_settings: Parametersdata object containing a dictionary with the data needed to run phonopy:
            supercells matrix, primitive matrix and q-points mesh.
    :param force_constants: (optional)ForceConstantsData object containing the 2nd order force constants
    :param force_sets: (optional) ForceSetsData object containing the phonopy force sets
    :param nac: (optional) ArrayData object from a single point calculation data containing dielectric tensor and Born charges
    :return: phonon band structure, force constants, thermal properties and DOS
    """

    structure = kwargs.pop('structure')
    ph_settings = kwargs.pop('ph_settings')
    bands = kwargs.pop('bands')

    from phonopy import Phonopy

    phonon = Phonopy(phonopy_bulk_from_structure(structure),
                     supercell_matrix=ph_settings.dict.supercell,
                     primitive_matrix=ph_settings.dict.primitive,
                     symprec=ph_settings.dict.symmetry_precision)

    if 'force_constants' in kwargs:
        force_constants = kwargs.pop('force_constants')
        phonon.set_force_constants(force_constants.get_data())

    else:
        force_sets = kwargs.pop('force_sets')
        phonon.set_displacement_dataset(force_sets.get_force_sets())
        phonon.produce_force_constants()
        force_constants = ForceConstantsData(data=phonon.get_force_constants())

    if 'nac_data' in kwargs:
        print('use born charges')
        nac_data = kwargs.pop('nac_data')
        primitive = phonon.get_primitive()
        nac_parameters = nac_data.get_born_parameters_phonopy(
            primitive_cell=primitive.get_cell())
        phonon.set_nac_params(nac_parameters)

    # Normalization factor primitive to unit cell
    normalization_factor = phonon.unitcell.get_number_of_atoms(
    ) / phonon.primitive.get_number_of_atoms()

    # DOS
    phonon.set_mesh(ph_settings.dict.mesh,
                    is_eigenvectors=True,
                    is_mesh_symmetry=False)
    phonon.set_total_DOS(tetrahedron_method=True)
    phonon.set_partial_DOS(tetrahedron_method=True)

    total_dos = phonon.get_total_DOS()
    partial_dos = phonon.get_partial_DOS()
    dos = PhononDosData(
        frequencies=total_dos[0],
        dos=total_dos[1] * normalization_factor,
        partial_dos=np.array(partial_dos[1]) * normalization_factor,
        atom_labels=np.array(phonon.primitive.get_chemical_symbols()))

    # THERMAL PROPERTIES (per primtive cell)
    phonon.set_thermal_properties()
    t, free_energy, entropy, cv = phonon.get_thermal_properties()

    # Stores thermal properties (per unit cell) data in DB as a workflow result
    thermal_properties = ArrayData()
    thermal_properties.set_array('temperature', t)
    thermal_properties.set_array('free_energy',
                                 free_energy * normalization_factor)
    thermal_properties.set_array('entropy', entropy * normalization_factor)
    thermal_properties.set_array('heat_capacity', cv * normalization_factor)

    # BAND STRUCTURE
    phonon.set_band_structure(bands.get_bands())
    band_structure = BandStructureData(bands=bands.get_bands(),
                                       labels=bands.get_labels(),
                                       unitcell=bands.get_unitcell())

    band_structure.set_band_structure_phonopy(phonon.get_band_structure())
    return {
        'thermal_properties': thermal_properties,
        'dos': dos,
        'band_structure': band_structure,
        'force_constants': force_constants
    }