Exemple #1
0
def get_phonon_configs(calc, at, disps, scell, config_type):

    cell = PhonopyAtoms(symbols=at.get_chemical_symbols(),
                        cell=at.get_cell(),
                        positions=at.get_positions())

    phonon = Phonopy(cell, np.eye(3) * scell)

    al = []

    for disp in disps:
        print(disp, config_type)
        phonon.generate_displacements(distance=disp)
        supercells = phonon.get_supercells_with_displacements()

        for (i, scell) in enumerate(supercells):
            at = ase.Atoms(symbols=scell.get_chemical_symbols(),
                           scaled_positions=scell.get_scaled_positions(),
                           cell=scell.get_cell(),
                           pbc=True)

            at.set_calculator(calc)
            e = at.get_potential_energy()
            f = at.get_forces()
            v = -1.0 * at.get_volume() * at.get_stress(voigt=False)
            at.arrays["force"] = f
            at.info["virial"] = v
            at.info["config_type"] = "PH_" + config_type
            at.info["energy_TB"] = e
            #write("PH_{}_{}_scell_{}.xyz".format(config_type, i, disp), at)
            al.append(at)

    return al
Exemple #2
0
def run_phonolammps():
    n = 2
    phlammps = Phonolammps('in.graphene',
                           supercell_matrix=[[n, 0, 0], [0, n, 0], [0, 0, n]])
    unitcell = phlammps.get_unitcell()
    force_constants = phlammps.get_force_constants()
    supercell_matrix = phlammps.get_supercell_matrix()
    print('unitcell')
    print('*' * 50)
    print(unitcell)
    print('force const')
    print('*' * 50)
    print(force_constants)
    print('supercell')
    print('*' * 50)
    print(supercell_matrix)

    from phonopy import Phonopy
    phonon = Phonopy(unitcell, supercell_matrix)
    print(phonon)
    print(dir(phonon))

    phonon.set_force_constants(force_constants)
    phonon.set_mesh([20, 20, 20])

    # phonon.write_yaml_band_structure('band.conf')
    # phonon.set_band_structure('band.conf')
    # phonon.plot_band_structure().savefig('band.png')

    # phonon.set_total_DOS()
    # phonon.plot_total_DOS().savefig('dos.png')

    phonon.set_thermal_properties()
    # print(phonon.get_thermal_properties_dict())
    phonon.plot_thermal_properties().savefig('therm.png')
 def setup(self):
     phonon = Phonopy(self._bulk,
                      supercell_matrix=[[6, 0, 0], [0, 6, 0], [0, 0, 6]])
     self._phonon = phonon
     self._symmetry = self._phonon.get_symmetry()
     self._force_sets = parse_FORCE_SETS()
     phonon.get_displacement_dataset()
Exemple #4
0
def get_force_sets_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()

    # 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.generate_displacements(distance=phonopy_input['distance'])

    # Build data_sets from forces of supercells with displacments
    data_sets = phonon.get_displacement_dataset()
    for i, first_atoms in enumerate(data_sets['first_atoms']):
        first_atoms['forces'] = kwargs.pop(
            'force_{}'.format(i)).get_array('forces')[-1]

    data = ArrayData()
    data.set_array('force_sets', np.array(data_sets))

    return {'phonopy_output': data}
Exemple #5
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
Exemple #6
0
def create_supercells_with_displacements_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()

    # 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.generate_displacements(distance=phonopy_input['distance'])

    cells_with_disp = phonon.get_supercells_with_displacements()

    # Transform cells to StructureData and set them ready to return
    disp_cells = {}

    for i, phonopy_supercell in enumerate(cells_with_disp):
        supercell = StructureData(cell=phonopy_supercell.get_cell())
        for symbol, position in zip(phonopy_supercell.get_chemical_symbols(),
                                    phonopy_supercell.get_positions()):
            supercell.append_atom(position=position, symbols=symbol)
        disp_cells["structure_{}".format(i)] = supercell

    return disp_cells
Exemple #7
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
Exemple #8
0
    def __init__(self, model=None, structure=None, atom_disp=0.015, **kwargs):
        self.model = model
        self.structure = structure
        self.atom_disp = atom_disp
        self.qpoints, self.vertices = get_qpoints_and_vertices(self.structure)
        is_plusminus = kwargs.get('is_plusminus', True)
        is_diagonal = kwargs.get('is_diagonal', True)
        is_trigonal = kwargs.get('is_diagonal', False)
        supercell_matrix = kwargs.get('is_diagonal', None)
        ph_structure = get_phonopy_structure(self.structure)
        if supercell_matrix is None:
            supercell_matrix = np.eye(3) * np.array((1, 1, 1))
        self.phonon = Phonopy(unitcell=ph_structure, supercell_matrix=supercell_matrix)
        self.phonon.generate_displacements(distance=self.atom_disp,
                                      is_plusminus=is_plusminus,
                                      is_diagonal=is_diagonal,
                                      is_trigonal=is_trigonal)

        disp_supercells = self.phonon.get_supercells_with_displacements()
        # Perfect supercell structure
        init_supercell = self.phonon.get_supercell()
        # Structure list to be returned
        self.structure_list = [get_pmg_structure(init_supercell)]

        for c in disp_supercells:
            if c is not None:
                self.structure_list.append(get_pmg_structure(c))

        forces = self.model.calculate_forces(self.structure_list)
        self.phonon.set_forces(forces[1:])
        self.phonon.produce_force_constants()
        logging.info("Force constant produced") 
def test_nacl(ph_nacl: Phonopy):
    """Test displacements of NaCl 2x2x2."""
    dataset = deepcopy(ph_nacl.dataset)
    disp_ref = [[0, 0.01, 0.0, 0.0], [32, 0.01, 0.0, 0.0]]
    np.testing.assert_allclose(ph_nacl.displacements, disp_ref, atol=1e-8)
    ph_nacl.generate_displacements()
    np.testing.assert_allclose(ph_nacl.displacements, disp_ref, atol=1e-8)
    ph_nacl.dataset = dataset
def test_si(ph_si: Phonopy):
    """Test displacements of Si."""
    dataset = deepcopy(ph_si.dataset)
    disp_ref = [[0, 0.0, 0.0070710678118655, 0.0070710678118655]]
    np.testing.assert_allclose(ph_si.displacements, disp_ref, atol=1e-8)
    ph_si.generate_displacements()
    np.testing.assert_allclose(ph_si.displacements, disp_ref, atol=1e-8)
    ph_si.dataset = dataset
 def _get_phonon(self, cell):
     phonon = Phonopy(cell,
                      np.diag([1, 1, 1]),
                      is_auto_displacements=False)
     force_sets = parse_FORCE_SETS()
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     return phonon
def _get_phonon(spgtype, dim, pmat):
    cell = read_vasp(os.path.join(data_dir, "POSCAR_%s" % spgtype))
    phonon = Phonopy(cell, np.diag(dim), primitive_matrix=pmat)
    force_sets = parse_FORCE_SETS(
        filename=os.path.join(data_dir, "FORCE_SETS_%s" % spgtype))
    phonon.dataset = force_sets
    phonon.produce_force_constants()
    return phonon
 def input_files(self, path_POSCAR, path_FORCECONSTANT):
     bulk = read_vasp(path_POSCAR)
     self.phonon = Phonopy(bulk,
                           self.super_cell,
                           primitive_matrix=self.primitive_cell)
     force_constants = file_IO.parse_FORCE_CONSTANTS(path_FORCECONSTANT)
     self.phonon.set_force_constants(force_constants)
     return self.phonon
 def _get_phonon(self, spgtype, dim, pmat):
     cell = read_vasp(os.path.join(data_dir,"POSCAR_%s" % spgtype))
     phonon = Phonopy(cell,
                      np.diag(dim),
                      primitive_matrix=pmat)
     force_sets = parse_FORCE_SETS(filename=os.path.join(data_dir,"FORCE_SETS_%s" % spgtype))
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     return phonon
Exemple #15
0
 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.')
Exemple #16
0
def get_force_constants_from_phonopy(structure, ph_settings, force_sets):
    """
    Calculate the force constants locally using phonopy

    :param structure:
    :param phonopy_input: ParameterData object that contains phonopy settings
    :param force_sets: ForceSetsData object that contains the atomic forces and displacements info (datasets dict in phonopy)
    :return: ForceConstantsData object containing the 2nd order force constants calculated with phonopy
    """
    from phonopy import Phonopy

    # Generate phonopy phonon object

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

    phonon.generate_displacements(distance=ph_settings.dict.distance)

    # Build data_sets from forces of supercells with displacments
    phonon.set_displacement_dataset(force_sets.get_force_sets())
    phonon.produce_force_constants()

    force_constants = ForceConstantsData(data=phonon.get_force_constants())

    return {'force_constants': force_constants}
def obtain_eigenvectors_from_phonopy(structure, q_vector, NAC=False):

    #   Checking data
    force_atoms_file = structure.get_force_set().item(0)["natom"]
    force_atoms_input = np.product(np.diagonal(structure.get_super_cell_phonon())) * structure.get_number_of_atoms()

    if force_atoms_file != force_atoms_input:
        print("Error: FORCE_SETS file does not match with SUPERCELL MATRIX")
        exit()

    #   Preparing the bulk type object
    bulk = PhonopyAtoms(
        symbols=structure.get_atomic_types(),
        scaled_positions=structure.get_scaled_positions(),
        cell=structure.get_cell().T,
    )

    phonon = Phonopy(
        bulk,
        structure.get_super_cell_phonon(),
        primitive_matrix=structure.get_primitive_matrix(),
        is_auto_displacements=False,
    )

    # Non Analytical Corrections (NAC) from Phonopy [Frequencies only, eigenvectors no affected by this option]
    if NAC:
        print("Phonopy warning: Using Non Analytical Corrections")
        get_is_symmetry = True  # from phonopy:   settings.get_is_symmetry()
        primitive = phonon.get_primitive()
        nac_params = parse_BORN(primitive, get_is_symmetry)
        phonon.set_nac_params(nac_params=nac_params)

    phonon.set_displacement_dataset(copy.deepcopy(structure.get_force_set()))
    phonon.produce_force_constants()

    frequencies, eigenvectors = phonon.get_frequencies_with_eigenvectors(q_vector)

    # Making sure eigenvectors are orthonormal (can be omitted)
    if True:
        eigenvectors = eigenvectors_normalization(eigenvectors)
        print("Testing eigenvectors orthonormality")
        np.set_printoptions(precision=3, suppress=True)
        print(np.dot(eigenvectors.T, np.ma.conjugate(eigenvectors)).real)
        np.set_printoptions(suppress=False)

    # Arranging eigenvectors by atoms and dimensions
    number_of_dimensions = structure.get_number_of_dimensions()
    number_of_primitive_atoms = structure.get_number_of_primitive_atoms()

    arranged_ev = np.array(
        [
            [
                [eigenvectors[j * number_of_dimensions + k, i] for k in range(number_of_dimensions)]
                for j in range(number_of_primitive_atoms)
            ]
            for i in range(number_of_primitive_atoms * number_of_dimensions)
        ]
    )

    return arranged_ev, frequencies
Exemple #18
0
 def _get_phonon(self, cell):
     phonon = Phonopy(cell,
                      np.diag([2, 2, 2]),
                      primitive_matrix=[[0, 0.5, 0.5],
                                        [0.5, 0, 0.5],
                                        [0.5, 0.5, 0]])
     force_sets = parse_FORCE_SETS(filename="FORCE_SETS_moment")
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     supercell = phonon.get_supercell()
     born_elems = {'Na': [[1.08703, 0, 0],
                          [0, 1.08703, 0],
                          [0, 0, 1.08703]],
                   'Cl': [[-1.08672, 0, 0],
                          [0, -1.08672, 0],
                          [0, 0, -1.08672]]}
     born = [born_elems[s] for s in ['Na', 'Cl']]
     epsilon = [[2.43533967, 0, 0],
                [0, 2.43533967, 0],
                [0, 0, 2.43533967]]
     factors = 14.400
     phonon.set_nac_params({'born': born,
                            'factor': factors,
                            'dielectric': epsilon})
     return phonon
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
Exemple #20
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
Exemple #21
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
Exemple #22
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
def get_phonon(pk, pk_nac):
    n = load_node(pk)
    unitcell = phonopy_atoms_from_structure(n.inputs.structure)
    smat = n.outputs.phonon_setting_info['supercell_matrix']
    ph = Phonopy(unitcell, supercell_matrix=smat, primitive_matrix='auto')
    force_sets = n.outputs.force_sets.get_array('force_sets')
    dataset = n.outputs.phonon_setting_info['displacement_dataset']
    ph.dataset = dataset
    ph.forces = force_sets
    ph.nac_params = get_nac_params(pk_nac)

    return ph
Exemple #24
0
def phonopy_pre_process(cell, config_type, supercell_matrix=None):

    smat = [[3, 0, 0], [0, 3, 0], [0, 0, 3]]

    phonon = Phonopy(cell, smat)

    phonon.generate_displacements(distance=0.16)  #0.02
    print("[Phonopy] Atomic displacements:")
    disps = phonon.get_displacements()
    for d in disps:
        print("[Phonopy] %d %s" % (d[0], d[1:]))
    return phonon
Exemple #25
0
def get_displaced_structures(pmg_structure,
                             atom_disp=0.01,
                             supercell_matrix=None,
                             yaml_fname=None,
                             **kwargs):
    """
    Generate a set of symmetrically inequivalent displaced structures for
    phonon calculations.

    Args:
        pmg_structure (Structure): A pymatgen structure object.
        atom_disp (float): Atomic displacement. Default is 0.01 $\\AA$.
        supercell_matrix (3x3 array): Scaling matrix for supercell.
        yaml_fname (string): If not None, it represents the full path to
            the outputting displacement yaml file, e.g. disp.yaml.
        **kwargs: Parameters used in Phonopy.generate_displacement method.

    Return:
        A list of symmetrically inequivalent structures with displacements, in
        which the first element is the perfect supercell structure.
    """

    is_plusminus = kwargs.get("is_plusminus", "auto")
    is_diagonal = kwargs.get("is_diagonal", True)
    is_trigonal = kwargs.get("is_trigonal", False)

    ph_structure = get_phonopy_structure(pmg_structure)

    if supercell_matrix is None:
        supercell_matrix = np.eye(3) * np.array((1, 1, 1))

    phonon = Phonopy(unitcell=ph_structure, supercell_matrix=supercell_matrix)
    phonon.generate_displacements(distance=atom_disp,
                                  is_plusminus=is_plusminus,
                                  is_diagonal=is_diagonal,
                                  is_trigonal=is_trigonal)

    if yaml_fname is not None:
        displacements = phonon.get_displacements()
        directions = phonon.get_displacement_directions()
        write_disp_yaml(displacements=displacements,
                        supercell=phonon.get_supercell(),
                        directions=directions,
                        filename=yaml_fname)

    # Supercell structures with displacement
    disp_supercells = phonon.get_supercells_with_displacements()
    # Perfect supercell structure
    init_supercell = phonon.get_supercell()
    # Structure list to be returned
    structure_list = [get_pmg_structure(init_supercell)]

    for c in disp_supercells:
        if c is not None:
            structure_list.append(get_pmg_structure(c))

    return structure_list
    def test_rand_FCM(self):
        fcm = ForceConstantMatrix(
            self.piezo_struc, self.FCM, self.pointops, self.sharedops
        )
        fcm.get_FCM_operations()
        rand_FCM = fcm.get_rand_FCM()
        structure = pymatgen.io.phonopy.get_phonopy_structure(self.piezo_struc)
        pnstruc = Phonopy(structure, np.eye(3), np.eye(3))

        pnstruc.set_force_constants(rand_FCM)
        dyn = pnstruc.get_dynamical_matrix_at_q([0, 0, 0])
        dyn = np.reshape(dyn, (10, 3, 10, 3)).swapaxes(1, 2)
        dyn = np.real(dyn)
        numsites = len(self.piezo_struc)
        masses = []
        for j in range(numsites):
            masses.append(self.piezo_struc.sites[j].specie.atomic_mass)
        dynmass = np.zeros([numsites, numsites, 3, 3])
        for m in range(numsites):
            for n in range(numsites):
                dynmass[m][n] = dyn[m][n] / np.sqrt(masses[m]) / np.sqrt(masses[n])

        dynmass = np.reshape(np.swapaxes(dynmass, 1, 2), (10 * 3, 10 * 3))
        eigs, vecs = np.linalg.eig(dynmass)
        eigsort = np.argsort(np.abs(eigs))
        for i in range(3, len(eigs)):
            self.assertTrue(eigs[eigsort[i]] < 1e-06)
        # rand_FCM1 = np.reshape(rand_FCM1, (10,3,10,3)).swapaxes(1,2)

        dynmass = np.reshape(dynmass, (10, 3, 10, 3)).swapaxes(1, 2)
        for i in range(len(self.FCM_operations)):
            for j in range(len(self.FCM_operations[i][4])):
                self.assertTrue(
                    np.allclose(
                        self.FCM_operations[i][4][j].transform_tensor(
                            dynmass[self.FCM_operations[i][2]][
                                self.FCM_operations[i][3]
                            ]
                        ),
                        dynmass[self.FCM_operations[i][0]][self.FCM_operations[i][1]],
                        atol=1e-04,
                    )
                )

        for i in range(len(dynmass)):
            asum1 = np.zeros([3, 3])
            asum2 = np.zeros([3, 3])
            for j in range(len(dynmass[i])):
                asum1 += dynmass[i][j]
                asum2 += dynmass[j][i]
            self.assertTrue(np.allclose(asum1, np.zeros([3, 3]), atol=1e-05))
            self.assertTrue(np.allclose(asum2, np.zeros([3, 3]), atol=1e-05))
def get_data_from_dir(directory, i_volume):

    data_sets = file_IO.parse_FORCE_SETS(
        filename=directory + '/phonon-{0:02d}/FORCE_SETS'.format(i_volume))

    yaml_file = open(
        directory + '/phonon-{0:02d}/phonon.yaml'.format(i_volume), 'r')
    data = yaml.load_all(yaml_file).next()

    unit_cell = PhonopyAtoms(
        symbols=[item['symbol'] for item in data['points']],
        scaled_positions=[item['coordinates'] for item in data['points']],
        cell=data['lattice'])

    phonon = Phonopy(unit_cell, data['supercell_matrix'])

    phonon.set_displacement_dataset(data_sets)
    phonon.produce_force_constants()

    force_constants = phonon.get_force_constants()

    supercell = phonon.get_supercell()

    volume = unit_cell.get_volume()
    energy = data['electric_total_energy']

    return supercell, volume, energy, force_constants, data['supercell_matrix']
def read_phonopy(sposcar='SPOSCAR',
                 sc_mat=np.eye(3),
                 force_constants=None,
                 disp_yaml=None,
                 force_sets=None):
    if force_constants is None and (disp_yaml is None or force_sets is None):
        raise ValueError(
            "Either FORCE_CONSTANTS or (disp.yaml&FORCE_SETS) file should be provided."
        )
    atoms = read(sposcar)
    #vesta_view(atoms)
    primitive_matrix = inv(sc_mat)
    bulk = PhonopyAtoms(symbols=atoms.get_chemical_symbols(),
                        scaled_positions=atoms.get_scaled_positions(),
                        cell=atoms.get_cell())
    phonon = Phonopy(
        bulk,
        supercell_matrix=np.eye(3),
        primitive_matrix=primitive_matrix,
        #factor=factor,
        #symprec=symprec
    )

    if disp_yaml is not None:
        disp = parse_disp_yaml(filename=disp_yaml)
        phonon.set_displacement_dataset(disp)
    if force_sets is not None:
        fc = parse_FORCE_SETS(filename=force_sets)
        phonon.set_forces(fc)

    fc = parse_FORCE_CONSTANTS(force_constants)
    phonon.set_force_constants(fc)

    return phonon
Exemple #29
0
 def _get_phonon(self, cell):
     phonon = Phonopy(cell,
                      np.diag([2, 2, 2]),
                      primitive_matrix=[[0, 0.5, 0.5],
                                        [0.5, 0, 0.5],
                                        [0.5, 0.5, 0]])
     force_sets = parse_FORCE_SETS(filename=os.path.join(data_dir,"FORCE_SETS_moment"))
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     supercell = phonon.get_supercell()
     born_elems = {'Na': [[1.08703, 0, 0],
                          [0, 1.08703, 0],
                          [0, 0, 1.08703]],
                   'Cl': [[-1.08672, 0, 0],
                          [0, -1.08672, 0],
                          [0, 0, -1.08672]]}
     born = [born_elems[s] for s in ['Na', 'Cl']]
     epsilon = [[2.43533967, 0, 0],
                [0, 2.43533967, 0],
                [0, 0, 2.43533967]]
     factors = 14.400
     phonon.set_nac_params({'born': born,
                            'factor': factors,
                            'dielectric': epsilon})
     return phonon
Exemple #30
0
 def _get_phonon(self):
     cell = read_vasp(os.path.join(data_dir, "..", "POSCAR_NaCl"))
     phonon = Phonopy(cell,
                      np.diag([2, 2, 2]),
                      primitive_matrix=[[0, 0.5, 0.5],
                                        [0.5, 0, 0.5],
                                        [0.5, 0.5, 0]])
     filename = os.path.join(data_dir, "FORCE_SETS_NaCl")
     force_sets = parse_FORCE_SETS(filename=filename)
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     born_elems = {'Na': [[1.08703, 0, 0],
                          [0, 1.08703, 0],
                          [0, 0, 1.08703]],
                   'Cl': [[-1.08672, 0, 0],
                          [0, -1.08672, 0],
                          [0, 0, -1.08672]]}
     born = [born_elems[s] for s in ['Na', 'Cl']]
     epsilon = [[2.43533967, 0, 0],
                [0, 2.43533967, 0],
                [0, 0, 2.43533967]]
     factors = 14.400
     phonon.set_nac_params({'born': born,
                            'factor': factors,
                            'dielectric': epsilon})
     return phonon
    def get_rand_FCM(self, asum=15, force=10):
        """
        Generate a symmeterized force constant matrix from an unsymmeterized matrix
        that has no unstable modes and also obeys the acoustic sum rule through an
        iterative procedure

        Args:
            force (float): maximum force constant
            asum (int): number of iterations to attempt to obey the acoustic sum
                rule

        Return:
            NxNx3x3 np.array representing the force constant matrix

        """

        numsites = len(self.structure.sites)
        structure = pymatgen.io.phonopy.get_phonopy_structure(self.structure)
        pnstruc = Phonopy(structure, np.eye(3), np.eye(3))

        dyn = self.get_unstable_FCM(force)
        dyn = self.get_stable_FCM(dyn)

        dyn = np.reshape(dyn, (numsites, 3, numsites, 3)).swapaxes(1, 2)

        dynmass = np.zeros([len(self.structure), len(self.structure), 3, 3])
        masses = []
        for j in range(numsites):
            masses.append(self.structure.sites[j].specie.atomic_mass)
        dynmass = np.zeros([numsites, numsites, 3, 3])
        for m in range(numsites):
            for n in range(numsites):
                dynmass[m][n] = dyn[m][n] * np.sqrt(masses[m]) * np.sqrt(
                    masses[n])

        supercell = pnstruc.get_supercell()
        primitive = pnstruc.get_primitive()

        converter = dyntofc.DynmatToForceConstants(primitive, supercell)

        dyn = np.reshape(np.swapaxes(dynmass, 1, 2),
                         (numsites * 3, numsites * 3))

        converter.set_dynamical_matrices(dynmat=[dyn])

        converter.run()
        fc = converter.get_force_constants()

        return fc
Exemple #32
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 codename and version from vasprun.xml file
    code_name, code_version = get_code_version(xml=vasprun_path)
    force_constant_factor = 1.0
    if code_version[0:1] >= '6':
        force_constant_factor = 0.004091649655126895

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

    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.run_mesh(qpoint_mesh)
    ph.run_thermal_properties(t_min=t_min, t_max=t_max, t_step=t_step)
    # the thermal properties are for the unit cell
    tp_dict = ph.get_thermal_properties_dict()
    temperatures = tp_dict['temperatures']
    # convert the units into our expected eV/atom-form (and per K)
    f_vib = tp_dict['free_energy'] * J_per_mol_to_eV_per_atom*1000
    s_vib = tp_dict['entropy'] * J_per_mol_to_eV_per_atom
    cv_vib = tp_dict['heat_capacity'] * J_per_mol_to_eV_per_atom
    return temperatures, f_vib, s_vib, cv_vib, ph.force_constants, code_version
Exemple #33
0
 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(),
                 primitive_matrix=self.input["primitive_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.")
Exemple #34
0
 def build_phonon(self, atoms = None, 
                    supercell_matrix = None, 
                    primitive_matrix = None,
                    distance = None):
     if atoms is None:
         atoms = self.atoms
     phonon = Phonopy(atoms,
                     supercell_matrix,
                     primitive_matrix = primitive_matrix)
     phonon.generate_displacements(distance = distance)
     self.log("[Phonopy] Atomic displacements:")
     disps = phonon.get_displacements()
     for d in disps:
         self.log("[Phonopy] %d %s" % (d[0], d[1:]))
     self.phonon = phonon
Exemple #35
0
    def _set_phonon(self):
        if self._supercell_matrix is None:
            cell = sort_cell_by_symbols(
                get_crystallographic_cell(self.get_cell()))
            self._supercell_matrix = estimate_supercell_matrix(
                cell,
                max_num_atoms=self._max_num_atoms)
        else:
            cell = self.get_cell()

        phonopy_cell = cell2atoms(cell)
        self._phonon = Phonopy(phonopy_cell,
                               self._supercell_matrix,
                               primitive_matrix=self._primitive_matrix,
                               dynamical_matrix_decimals=14,
                               force_constants_decimals=14,
                               symprec=self._symmetry_tolerance)
        self._phonon.generate_displacements(
            distance=self._distance,
            is_plusminus=self._displace_plusminus,
            is_diagonal=self._displace_diagonal)
        supercell = self._phonon.get_supercell()
        displacements = self._phonon.get_displacements()

        write_poscar(cell, filename="POSCAR-unitcell")
        write_poscar_yaml(cell, filename="POSCAR-unitcell.yaml")
        write_disp_yaml(displacements, supercell)
Exemple #36
0
def phonopy_pre_process(cell, supercell_matrix=None):

    if supercell_matrix is None:
        smat = [[2,0,0], [0,2,0], [0,0,2]],
    else:
        smat = supercell_matrix
    phonon = Phonopy(cell,
                     smat,
                     primitive_matrix=[[0, 0.5, 0.5],
                                       [0.5, 0, 0.5],
                                       [0.5, 0.5, 0]])
    phonon.generate_displacements(distance=0.03)
    print("[Phonopy] Atomic displacements:")
    disps = phonon.get_displacements()
    for d in disps:
        print("[Phonopy] %d %s" % (d[0], d[1:]))
    return phonon
 def test_properties(self):
     cell = read_vasp(os.path.join(data_dir, "..", "POSCAR_NaCl"))
     phonon = Phonopy(cell,
                      np.diag([2, 2, 2]),
                      primitive_matrix=[[0, 0.5, 0.5],
                                        [0.5, 0, 0.5],
                                        [0.5, 0.5, 0]])
     filename = os.path.join(data_dir, "..", "FORCE_SETS_NaCl")
     force_sets = parse_FORCE_SETS(filename=filename)
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     dynmat = phonon.dynamical_matrix
     dynmat.set_dynamical_matrix([0, 0, 0])
     self.assertTrue(id(dynmat.primitive)
                     == id(dynmat.get_primitive()))
     self.assertTrue(id(dynmat.supercell)
                     == id(dynmat.get_supercell()))
     np.testing.assert_allclose(dynmat.dynamical_matrix,
                                dynmat.get_dynamical_matrix())
Exemple #38
0
def get_displaced_structures(pmg_structure, atom_disp=0.01,
                             supercell_matrix=None, yaml_fname=None, **kwargs):
    """
    Generate a set of symmetrically inequivalent displaced structures for
    phonon calculations.

    Args:
        pmg_structure (Structure): A pymatgen structure object.
        atom_disp (float): Atomic displacement. Default is 0.01 $\\AA$.
        supercell_matrix (3x3 array): Scaling matrix for supercell.
        yaml_fname (string): If not None, it represents the full path to
            the outputting displacement yaml file, e.g. disp.yaml.
        **kwargs: Parameters used in Phonopy.generate_displacement method.

    Return:
        A list of symmetrically inequivalent structures with displacements, in
        which the first element is the perfect supercell structure.
    """

    is_plusminus = kwargs.get("is_plusminus", "auto")
    is_diagonal = kwargs.get("is_diagonal", True)
    is_trigonal = kwargs.get("is_trigonal", False)

    ph_structure = get_phonopy_structure(pmg_structure)

    if supercell_matrix is None:
        supercell_matrix = np.eye(3) * np.array((1, 1, 1))

    phonon = Phonopy(unitcell=ph_structure, supercell_matrix=supercell_matrix)
    phonon.generate_displacements(distance=atom_disp,
                                  is_plusminus=is_plusminus,
                                  is_diagonal=is_diagonal,
                                  is_trigonal=is_trigonal)

    if yaml_fname is not None:
        displacements = phonon.get_displacements()
        directions = phonon.get_displacement_directions()
        write_disp_yaml(displacements=displacements,
                        supercell=phonon.get_supercell(),
                        directions=directions, filename=yaml_fname)

    # Supercell structures with displacement
    disp_supercells = phonon.get_supercells_with_displacements()
    # Perfect supercell structure
    init_supercell = phonon.get_supercell()
    # Structure list to be returned
    structure_list = [get_pmg_structure(init_supercell)]

    for c in disp_supercells:
        if c is not None:
            structure_list.append(get_pmg_structure(c))

    return structure_list
Exemple #39
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]))
 def _get_phonon_NaCl(self):
     cell = read_vasp(os.path.join(data_dir, "..", "POSCAR_NaCl"))
     phonon = Phonopy(cell,
                      np.diag([2, 2, 2]),
                      primitive_matrix=[[0, 0.5, 0.5],
                                        [0.5, 0, 0.5],
                                        [0.5, 0.5, 0]])
     filename = os.path.join(data_dir, "..", "FORCE_SETS_NaCl")
     force_sets = parse_FORCE_SETS(filename=filename)
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     filename_born = os.path.join(data_dir, "..", "BORN_NaCl")
     nac_params = parse_BORN(phonon.get_primitive(), filename=filename_born)
     phonon.set_nac_params(nac_params)
     return phonon
Exemple #41
0
def get_frequency(poscar_filename, force_sets_filename):
    bulk = read_vasp(poscar_filename)
    volume = bulk.get_volume()
    phonon = Phonopy(bulk, [[2, 0, 0], [0, 2, 0], [0, 0, 2]],
                     is_auto_displacements=False)
    force_sets = parse_FORCE_SETS(filename=force_sets_filename)
    phonon.set_force_sets(force_sets)
    phonon.set_post_process([[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]])
    return phonon.get_frequencies([0.5, 0.5, 0]), volume
Exemple #42
0
 def _get_phonon(self):
     cell = read_vasp(os.path.join(data_dir, "../POSCAR_NaCl"))
     phonon = Phonopy(cell, np.diag([2, 2, 2]), primitive_matrix=[[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]])
     filename = os.path.join(data_dir, "FORCE_SETS_NaCl")
     force_sets = parse_FORCE_SETS(filename=filename)
     phonon.set_displacement_dataset(force_sets)
     phonon.produce_force_constants()
     supercell = phonon.get_supercell()
     born_elems = {
         "Na": [[1.08703, 0, 0], [0, 1.08703, 0], [0, 0, 1.08703]],
         "Cl": [[-1.08672, 0, 0], [0, -1.08672, 0], [0, 0, -1.08672]],
     }
     born = [born_elems[s] for s in ["Na", "Cl"]]
     epsilon = [[2.43533967, 0, 0], [0, 2.43533967, 0], [0, 0, 2.43533967]]
     factors = 14.400
     phonon.set_nac_params({"born": born, "factor": factors, "dielectric": epsilon})
     return phonon
Exemple #43
0
    def _set_phonon(self):
        cell = self.get_cell()
        phonopy_cell = cell2atoms(cell)
        self._phonon = Phonopy(phonopy_cell,
                               self._supercell_matrix,
                               primitive_matrix=self._primitive_matrix,
                               is_auto_displacements=False,
                               dynamical_matrix_decimals=14,
                               force_constants_decimals=14)
        self._phonon.generate_displacements(
            distance=self._distance,
            is_plusminus=self._displace_plusminus,
            is_diagonal=self._displace_diagonal)
        supercell = self._phonon.get_supercell()
        displacements = self._phonon.get_displacements()

        write_poscar(cell, "POSCAR-unitcell")
        write_disp_yaml(displacements, supercell)
Exemple #44
0
    def _set_phonon(self):
        cell = self.get_cell()
        phonopy_cell = Atoms(
            cell=cell.get_lattice().T,
            scaled_positions=cell.get_points().T,
            symbols=cell.get_symbols())
        
        self._phonon = Phonopy(phonopy_cell,
                               self._supercell_matrix,
                               is_auto_displacements=False)
        self._phonon.generate_displacements(distance=self._distance,
                                            is_diagonal=False)

        supercell = self._phonon.get_supercell()
        displacements = self._phonon.get_displacements()

        write_poscar(cell, "POSCAR-unitcell")
        write_disp_yaml(displacements, supercell)
Exemple #45
0
 def _set_phonon_fc3(self):
     cell = self.get_cell()
     phonopy_cell = cell2atoms(cell)
     self._phonon = Phonopy(phonopy_cell,
                            self._supercell_matrix,
                            primitive_matrix=self._primitive_matrix,
                            dynamical_matrix_decimals=14,
                            force_constants_decimals=14)
     self._phonon_fc3 = Phono3py(phonopy_cell,
                                 self._supercell_matrix,
                                 primitive_matrix=self._primitive_matrix)
     self._phonon_fc3.generate_displacements(distance=self._distance,
                                             is_diagonal=self._is_diagonal)
     supercell = self._phonon_fc3.get_supercell()
     disp_dataset = self._phonon_fc3.get_displacement_dataset()
     self._phonon.set_displacement_dataset(disp_dataset)
     write_poscar(cell, "POSCAR-unitcell")
     write_disp_yaml(self._phonon.get_displacements(),
                     supercell,
                     directions=self._phonon.get_displacement_directions())
     write_disp_fc3_yaml(disp_dataset, supercell)
Exemple #46
0
 def _get_phonon(self, cell):
     phonon = Phonopy(cell, np.diag([1, 1, 1]))
     force_sets = parse_FORCE_SETS(
         filename=os.path.join(data_dir, "FORCE_SETS"))
     phonon.dataset = force_sets
     phonon.produce_force_constants()
     supercell = phonon.get_supercell()
     born_elems = {'Na': [[1.08703, 0, 0],
                          [0, 1.08703, 0],
                          [0, 0, 1.08703]],
                   'Cl': [[-1.08672, 0, 0],
                          [0, -1.08672, 0],
                          [0, 0, -1.08672]]}
     born = [born_elems[s]
             for s in supercell.get_chemical_symbols()]
     epsilon = [[2.43533967, 0, 0],
                [0, 2.43533967, 0],
                [0, 0, 2.43533967]]
     factors = 14.400
     phonon.set_nac_params({'born': born,
                            'factor': factors,
                            'dielectric': epsilon})
     return phonon
Exemple #47
0
import phonopy.interface.vasp as vasp
import numpy as np
import lxml.etree as etree
from phonopy import Phonopy
from phonopy.structure.atoms import Atoms as PhonopyAtoms


vasprun = etree.iterparse('vasprun.xml', tag='varray')
fc = vasp.get_force_constants_vasprun_xml(vasprun)

primitive = vasp.get_atoms_from_poscar(open('POSCAR-p'),'W')
superc =  vasp.get_atoms_from_poscar(open('POSCAR'),'W')

print superc.get_scaled_positions()

a = 5.404
bulk = PhonopyAtoms(symbols=['W'] * 216,
                    positions=superc.get_scaled_positions())
bulk.set_cell(np.diag((a, a, a)))
phonon = Phonopy(bulk,[[1,0,0],[0,1,0],[0,0,1]],primitive_matrix=[[-0.5, 0.5, 0.5],[0.5, -0.5, 0.5],[0.5, 0.5, -0.5]])

phonon.set_force_constants(fc)

mesh = [3, 3, 3]
phonon.set_mesh(mesh)
qpoints, weights, frequencies, eigvecs = phonon.get_mesh()


phonon.set_total_DOS()
phonon.plot_total_DOS().show()
Exemple #48
0
                                      (0, 0.5, 0.5),
                                      (0.5, 0, 0.5),
                                      (0.5, 0.5, 0),
                                      (0.25, 0.25, 0.25),
                                      (0.25, 0.75, 0.75),
                                      (0.75, 0.25, 0.75),
                                      (0.75, 0.75, 0.25)] )
bulk.set_cell(np.diag((a, a, a)))

calc = GPAW(mode=PW(300),
            kpts={'size': (4, 4, 4)},
            symmetry={'symmorphic': False})

phonon = Phonopy(bulk,
                 [[1,0,0],[0,1,0],[0,0,1]],
                 primitive_matrix=[[0, 0.5, 0.5],
                                   [0.5, 0, 0.5],
                                   [0.5, 0.5, 0]],
                 distance=0.01)
print "[Phonopy] Atomic displacements:"
disps = phonon.get_displacements()
for d in disps:
    print "[Phonopy]", d[0], d[1:]
supercells = phonon.get_supercells_with_displacements()

# Force calculations by calculator
set_of_forces = []
for scell in supercells:
    cell = Atoms(symbols=scell.get_chemical_symbols(),
                 scaled_positions=scell.get_scaled_positions(),
                 cell=scell.get_cell(),
                 pbc=True)
Exemple #49
0
from phonopy import Phonopy
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_FORCE_SETS
from phonopy.file_IO import parse_FORCE_CONSTANTS, write_FORCE_CONSTANTS

cell = read_vasp("POSCAR")
phonon = Phonopy(cell, [[2, 0, 0], [0, 2, 0], [0, 0, 2]])
force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()
write_FORCE_CONSTANTS(phonon.get_force_constants(), filename="FORCE_CONSTANTS")

force_constants = parse_FORCE_CONSTANTS()
phonon.set_force_constants(force_constants)
phonon.symmetrize_force_constants(iteration=1)
write_FORCE_CONSTANTS(phonon.get_force_constants(), filename="FORCE_CONSTANTS_NEW")
Exemple #50
0
class PhononBase(TaskElement):
    """PhononBase class

    This is an interface to phonopy.

    """

    def __init__(self,
                 directory=None,
                 name=None,
                 supercell_matrix=None,
                 primitive_matrix=None,
                 distance=None,
                 lattice_tolerance=None,
                 force_tolerance=None,
                 pressure_target=None,
                 stress_tolerance=None,
                 max_increase=None,
                 max_iteration=None,
                 min_iteration=None,
                 traverse=False,
                 is_cell_relaxed=False):

        TaskElement.__init__(self)

        self._directory = directory
        if not name:
            self._name = directory
        else:
            self._name = name
        self._task_type = "phonon"
        self._supercell_matrix = supercell_matrix
        self._primitive_matrix = primitive_matrix
        self._distance = distance
        self._lattice_tolerance = lattice_tolerance
        self._pressure_target = pressure_target
        self._stress_tolerance = stress_tolerance
        self._force_tolerance = force_tolerance
        self._max_increase = max_increase
        self._max_iteration = max_iteration
        self._min_iteration = min_iteration
        self._traverse = traverse
        self._is_cell_relaxed = is_cell_relaxed

        self._stage = 0
        self._tasks = []

        self._energy = None
        self._cell = None
        self._phonon = None # Phonopy object

    def get_phonon(self):
        return self._phonon

    def get_cell(self):
        if self._is_cell_relaxed:
            return self._cell
        else:
            return self._phonon_tasks[0].get_cell()

    def get_energy(self):
        """Return energies at geometry optimization steps"""
        return self._energy

    def set_status(self):
        done = True
        terminate = False
        for task in self._tasks:
            done &= task.done()
            if task.get_status() == "terminate":
                terminate = True
        if done:
            if terminate:
                self._status = "terminate"
            else:
                self._status = "next"

        self._write_yaml()

    def begin(self):
        if not self._job:
            print "set_job has to be executed."
            raise

        self._overwrite_settings()

        if self._is_cell_relaxed:
            self._phonon_tasks = [None]
            self._set_stage1()
        else:
            self._set_stage0()

    def end(self):
        pass

    def done(self):
        return ("terminate" in self._status or 
                "done" in self._status or
                "next" in self._status)

    def next(self):
        if self._stage == 0:
            if "next" in self._status:
                self._energy = self._tasks[0].get_energy()
                self._comment = "%s\\n%f" % (
                    self._tasks[0].get_space_group()['international_standard'],
                    self._energy)
                self._set_stage1()
                return self._tasks
            elif "terminate" in self._status and self._traverse == "restart":
                self._traverse = False
                self._set_stage0()
                return self._tasks
            else:
                raise StopIteration
        else: # task 1..n: displaced supercells
            if "next" in self._status:
                self._status = "done"
                forces = []
                for task in self._phonon_tasks[1:]:
                    forces.append(task.get_properties()['forces'][-1])
                self._write_FORCE_SETS(forces)
                self._phonon.set_post_process(self._primitive_matrix,
                                              forces,
                                              force_constants_decimals=14)
                self._tasks = []
                raise StopIteration
            elif "terminate" in self._status and self._traverse == "restart":
                self._traverse = False
                disp_terminated = []
                for i, task in enumerate(self._tasks):
                    if task.get_status() == "terminate":
                        disp_terminated.append(i)
                tasks = self._get_displacement_tasks()[1:]
                self._tasks = []
                for i in disp_terminated:
                    self._tasks.append(tasks[i])
                    self._phonon_tasks[i + 1] = tasks[i]
                self._status = "displacements"
                return self._tasks
            else:
                raise StopIteration

    def _set_stage0(self):
        self._status = "equilibrium"
        task = self._get_equilibrium_task()
        self._phonon_tasks = [task]
        self._tasks = [task]
        
    def _set_stage1(self):
        self._stage = 1
        self._status = "displacements"
        self._set_phonon()
        self._tasks = self._get_displacement_tasks()[1:]
        self._phonon_tasks += self._tasks

    def _set_phonon(self):
        cell = self.get_cell()
        phonopy_cell = Atoms(
            cell=cell.get_lattice().T,
            scaled_positions=cell.get_points().T,
            symbols=cell.get_symbols())
        
        self._phonon = Phonopy(phonopy_cell,
                               self._supercell_matrix,
                               is_auto_displacements=False)
        self._phonon.generate_displacements(distance=self._distance,
                                            is_diagonal=False)

        supercell = self._phonon.get_supercell()
        displacements = self._phonon.get_displacements()

        write_poscar(cell, "POSCAR-unitcell")
        write_disp_yaml(displacements, supercell)

    def _write_FORCE_SETS(self, forces):
        displacements = [[x[0], x[1:4]]
                         for x in self._phonon.get_displacements()]
        natom = self._phonon.get_supercell().get_number_of_atoms()
        write_FORCE_SETS("FORCE_SETS",
                         natom,
                         displacements,
                         forces,
                         verbose=False)

    def _write_yaml(self):
        w = open("%s.yaml" % self._directory, 'w')
        if self._phonon_tasks[0]:
            if self._lattice_tolerance is not None:
                w.write("lattice_tolerance: %f\n" % self._lattice_tolerance)
            if self._stress_tolerance is not None:
                w.write("stress_tolerance: %f\n" % self._stress_tolerance)
                w.write("pressure_target: %f\n" % self._pressure_target)
            w.write("force_tolerance: %f\n" % self._force_tolerance)
            w.write("max_increase: %f\n" % self._max_increase)
            w.write("max_iteration: %d\n" % self._max_iteration)
            w.write("min_iteration: %d\n" % self._min_iteration)
            w.write("supercell_matrix:\n")
            for row in self._supercell_matrix:
                w.write("- [ %3d, %3d, %3d ]\n" % tuple(row))
            w.write("primitive_matrix:\n")
            for row in self._primitive_matrix:
                w.write("- [ %6.3f, %6.3f, %6.3f ]\n" % tuple(row))
            w.write("distance: %f\n" % self._distance)
            w.write("iteration: %d\n" % self._phonon_tasks[0].get_stage())
            if self._energy:
                w.write("electric_total_energy: %20.10f\n" % self._energy)
        w.write("status: %s\n" % self._status)
        w.write("tasks:\n")
        for task in self._phonon_tasks:
            if task and task.get_status():
                w.write("- name:   %s\n" % task.get_name())
                w.write("  status: %s\n" % task.get_status())
        w.close()
Exemple #51
0
# This can be given via a PhonopyAtoms class as follows:
# unitcell = PhonopyAtoms(symbols=(['Na'] * 4 + ['Cl'] * 4),
#                         cell=(np.eye(3) * 5.6903014761756712),
#                         scaled_positions=[[0, 0, 0],
#                                           [0, 0.5, 0.5],
#                                           [0.5, 0, 0.5],
#                                           [0.5, 0.5, 0],
#                                           [0.5, 0.5, 0.5],
#                                           [0.5, 0, 0],
#                                           [0, 0.5, 0],
#                                           [0, 0, 0.5]])

phonon = Phonopy(unitcell,
                 [[2, 0, 0],
                  [0, 2, 0],
                  [0, 0, 2]],
                 primitive_matrix=[[0, 0.5, 0.5],
                                   [0.5, 0, 0.5],
                                   [0.5, 0.5, 0]])

symmetry = phonon.get_symmetry()
print "Space group:", symmetry.get_international_table()

force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()
primitive = phonon.get_primitive()

# Born effective charges and dielectric constants are read from BORN file.
nac_params = parse_BORN(primitive, filename="BORN")
# Or it can be of course given by hand as follows:
Exemple #52
0
from phonopy import Phonopy
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_FORCE_SETS, parse_BORN
import numpy as np

cell = read_vasp("POSCAR")

# Initialize phonon. Supercell matrix has to have the shape of (3, 3)
phonon = Phonopy(cell, np.diag([3, 3, 2]))

symmetry = phonon.get_symmetry()
print "Space group:", symmetry.get_international_table()

force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()

# Character table
phonon.set_irreps([1./3, 1./3, 0], 1e-4)
ct = phonon.get_irreps() 
band_indices = ct.get_band_indices()
characters = np.rint(ct.get_characters()).real
for bi, cts in zip(band_indices, characters):
    print np.array(bi) + 1, cts
# phonon.show_character_table()
Exemple #53
0
calc = GPAW(gpts=(n, n, n),
            nbands=8*3,
            width=0.01,
            kpts=(2, 2, 2),
            convergence={'eigenstates': 1e-9}
            )

# Phonopy pre-process
print "------"
print "Phonon"
print "------"
# 1st arg. is the input unit cell.
# 2nd arg. is the supercell lattice relative to the unit cell.
# 'distance' is the distance of displacements.
# Default symmetry tolerance is 1e-5 in fractional coordinates.
phonon = Phonopy(bulk, [[1,0,0],[0,1,0],[0,0,1]], distance=0.01)
phonon.print_displacements()
supercells = phonon.get_supercells_with_displacements()

# Force calculations by calculator
set_of_forces = []
for scell in supercells:
    cell = Atoms( symbols=scell.get_chemical_symbols(),
                  scaled_positions=scell.get_scaled_positions(),
                  cell=scell.get_cell(),
                  pbc=True )
    cell.set_calculator(calc)
    forces = cell.get_forces()
    drift_force = forces.sum(axis=0)
    print "        ---------------------------------"
    print "     ", "%11.5f"*3 % tuple(drift_force)
Exemple #54
0
from phonopy import Phonopy
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_FORCE_SETS, parse_BORN
import numpy as np

cell = read_vasp("POSCAR")

# Initialize phonon. Supercell matrix has to have the shape of (3, 3)
phonon = Phonopy(cell, np.diag([2, 2, 1]))

symmetry = phonon.get_symmetry()
print "Space group:", symmetry.get_international_table()

# Read and convert forces and displacements
force_sets = parse_FORCE_SETS(cell.get_number_of_atoms() * 4)
# Sets of forces have to be set before phonon.set_post_process or
# at phonon.set_post_process(..., sets_of_forces=sets_of_forces, ...).
phonon.set_force_sets(force_sets)

# To activate non-analytical term correction.
phonon.set_post_process(primitive_matrix=[[2./3, -1./3, -1./3],
                                          [1./3, 1./3, -2./3],
                                          [1./3, 1./3, 1./3]])

# Parameters for non-analytical term correction can be set
# also after phonon.set_post_process
born = parse_BORN(phonon.get_primitive())
phonon.set_nac_params(born)

# Example to obtain dynamical matrix
dmat = phonon.get_dynamical_matrix_at_q([0,0,0])
Exemple #55
0
#!/usr/bin/env python

from cogue.task.phonon_relax import get_unstable_modulations
from phonopy import Phonopy
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_FORCE_SETS, parse_BORN
import numpy as np

cutoff_eigenvalue = -0.02
supercell_dimension = [2, 2, 2]
cell = read_vasp("POSCAR-unitcell")
phonon = Phonopy(cell, np.diag(supercell_dimension))
force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()
phonon.set_mesh(supercell_dimension, is_gamma_center=True)

get_unstable_modulations(
    phonon, supercell_dimension, cutoff_eigenvalue=cutoff_eigenvalue, symmetry_tolerance=0.1, max_displacement=0.11
)
Exemple #56
0
from phonopy import Phonopy
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_FORCE_SETS, parse_BORN
import numpy as np

cell = read_vasp("POSCAR")

# Initialize phonon. Supercell matrix has to have the shape of (3, 3)
phonon = Phonopy(cell,
                 np.diag([2, 2, 1]),
                 primitive_matrix=[[2./3, -1./3, -1./3],
                                   [1./3, 1./3, -2./3],
                                   [1./3, 1./3, 1./3]])

symmetry = phonon.get_symmetry()
print "Space group:", symmetry.get_international_table()

force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()

born = parse_BORN(phonon.get_primitive())
phonon.set_nac_params(born)

# Example to obtain dynamical matrix
dmat = phonon.get_dynamical_matrix_at_q([0,0,0])
print dmat

# Example of band structure calculation
bands = []
q_start = np.array([1./3, 1./3, 0])
Exemple #57
0
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_FORCE_SETS, parse_BORN
import numpy as np

def append_band(bands, q_start, q_end):
    band = []
    for i in range(51):
        band.append(np.array(q_start) +
                    (np.array(q_end) - np.array(q_start)) / 50 * i)
    bands.append(band)

bulk = read_vasp("POSCAR")
phonon = Phonopy(bulk,
                 [[2, 0, 0],
                  [0, 2, 0],
                  [0, 0, 2]],
                 primitive_matrix=[[0, 0.5, 0.5],
                                   [0.5, 0, 0.5],
                                   [0.5, 0.5, 0]],
                 is_auto_displacements=False)

symmetry = phonon.get_symmetry()
print "Space group:", symmetry.get_international_table()

force_sets = parse_FORCE_SETS()
phonon.set_displacement_dataset(force_sets)
phonon.produce_force_constants()

born = [[[1.08703, 0, 0],
         [0, 1.08703, 0],
         [0, 0, 1.08703]],
        [[-1.08672, 0, 0],
Exemple #58
0
class PhononBase(TaskElement):
    """PhononBase class

    This is an interface to phonopy.

    """

    def __init__(self,
                 directory=None,
                 name=None,
                 supercell_matrix=None,
                 primitive_matrix=None,
                 distance=None,
                 displace_plusminus='auto',
                 displace_diagonal=False,
                 lattice_tolerance=None,
                 force_tolerance=None,
                 pressure_target=None,
                 stress_tolerance=None,
                 max_increase=None,
                 max_iteration=None,
                 min_iteration=None,
                 is_cell_relaxed=False,
                 stop_condition=None,
                 traverse=False):

        TaskElement.__init__(self)

        self._directory = directory
        if not name:
            self._name = directory
        else:
            self._name = name
        self._task_type = "phonon"
        self._supercell_matrix = supercell_matrix
        self._primitive_matrix = primitive_matrix
        self._distance = distance
        self._displace_plusminus = displace_plusminus
        self._displace_diagonal = displace_diagonal
        self._lattice_tolerance = lattice_tolerance
        self._pressure_target = pressure_target
        self._stress_tolerance = stress_tolerance
        self._force_tolerance = force_tolerance
        self._max_increase = max_increase
        self._max_iteration = max_iteration
        self._min_iteration = min_iteration
        self._is_cell_relaxed = is_cell_relaxed
        self._stop_condition = stop_condition
        self._traverse = traverse

        self._stage = 0
        self._tasks = []

        self._energy = None
        self._space_group = None
        self._cell = None
        self._phonon = None # Phonopy object
        self._phonon_tasks = None # Phonopy object

    def get_phonon(self):
        return self._phonon

    def get_cell(self):
        if self._is_cell_relaxed:
            return self._cell
        else:
            return self._phonon_tasks[0].get_cell()

    def get_energy(self):
        """Return energies at geometry optimization steps"""
        return self._energy

    def get_space_group(self):
        return self._space_group
        
    def set_status(self):
        if self._stage == 0:
            task = self._tasks[0]
            if task.done():
                self._space_group = task.get_space_group()
                status = task.get_status()
                if status == "done":
                    if not self._evaluate_stop_condition():
                        self._status = "next"
                else:
                    self._status = status
        else:
            done = True
            terminate = True
            for task in self._tasks:
                done &= task.done()
                terminate &= (task.get_status() == "terminate")
                
            if done:
                if terminate:
                    self._status = "terminate"
                else:
                    self._status = "next"

        self._write_yaml()

    def begin(self):
        if not self._job:
            print "set_job has to be executed."
            raise

        self._overwrite_settings()

        if self._is_cell_relaxed:
            self._phonon_tasks = [None]
            self._set_stage1()
        else:
            self._set_stage0()

    def done(self):
        return (self._status == "terminate" or
                self._status == "done" or
                self._status == "max_iteration" or
                self._status == "low_symmetry" or
                self._status == "next")

    def next(self):
        if self._stage == 0:
            if self._status == "next":
                self._energy = self._tasks[0].get_energy()
                num_atom = len(self._tasks[0].get_cell().get_symbols())
                self._comment = self._space_group['international_standard']
                self._comment += "\\n%f/%d" % (self._energy, num_atom)
                self._set_stage1()
                return self._tasks
            elif (self._status == "terminate" and self._traverse == "restart"):
                self._traverse = False
                self._set_stage0()
                return self._tasks
                
        else: # task 1..n: displaced supercells
            if self._status == "next":
                self._status = "done"
                forces = []
                for task in self._tasks:
                    forces.append(task.get_properties()['forces'][-1])
                self._phonon.produce_force_constants(forces)
                write_FORCE_SETS(self._phonon.get_displacement_dataset())
                self._tasks = []
            elif self._status == "terminate" and self._traverse == "restart":
                self._traverse = False
                disp_terminated = []
                for i, task in enumerate(self._tasks):
                    if task.get_status() == "terminate":
                        disp_terminated.append(i)
                tasks = self._get_displacement_tasks()
                self._tasks = []
                for i in disp_terminated:
                    self._tasks.append(tasks[i])
                    self._phonon_tasks[i + 1] = tasks[i]
                self._status = "displacements"
                return self._tasks
                
        self._write_yaml()
            
        raise StopIteration

    def _set_stage0(self):
        self._status = "equilibrium"
        task = self._get_equilibrium_task()
        self._phonon_tasks = [task]
        self._tasks = [task]
        
    def _set_stage1(self):
        self._stage = 1
        self._status = "displacements"
        self._set_phonon()
        self._tasks = self._get_displacement_tasks()
        self._phonon_tasks += self._tasks

    def _evaluate_stop_condition(self):
        if self._stop_condition:
            if "symmetry_operations" in self._stop_condition:
                num_ops = len(self._space_group['rotations'])
                if (num_ops <
                    self._stop_condition['symmetry_operations']):
                    self._status = "low_symmetry"
                    return True
                    
        return False
        
    def _set_phonon(self):
        cell = self.get_cell()
        phonopy_cell = cell2atoms(cell)
        self._phonon = Phonopy(phonopy_cell,
                               self._supercell_matrix,
                               primitive_matrix=self._primitive_matrix,
                               is_auto_displacements=False,
                               dynamical_matrix_decimals=14,
                               force_constants_decimals=14)
        self._phonon.generate_displacements(
            distance=self._distance,
            is_plusminus=self._displace_plusminus,
            is_diagonal=self._displace_diagonal)
        supercell = self._phonon.get_supercell()
        displacements = self._phonon.get_displacements()

        write_poscar(cell, "POSCAR-unitcell")
        write_disp_yaml(displacements, supercell)

    def _write_yaml(self):
        w = open("%s.yaml" % self._directory, 'w')
        w.write("supercell_matrix:\n")
        for row in self._supercell_matrix:
            w.write("- [ %3d, %3d, %3d ]\n" % tuple(row))
        w.write("primitive_matrix:\n")
        for row in self._primitive_matrix:
            w.write("- [ %6.3f, %6.3f, %6.3f ]\n" % tuple(row))
        w.write("distance: %f\n" % self._distance)
        
        if self._phonon_tasks[0]:
            if self._lattice_tolerance is not None:
                w.write("lattice_tolerance: %f\n" % self._lattice_tolerance)
            if self._stress_tolerance is not None:
                w.write("stress_tolerance: %f\n" % self._stress_tolerance)
                w.write("pressure_target: %f\n" % self._pressure_target)
            w.write("force_tolerance: %f\n" % self._force_tolerance)
            if self._max_increase is None:
                w.write("max_increase: unset\n")
            else:
                w.write("max_increase: %f\n" % self._max_increase)
            w.write("max_iteration: %d\n" % self._max_iteration)
            w.write("min_iteration: %d\n" % self._min_iteration)
            w.write("iteration: %d\n" % self._phonon_tasks[0].get_stage())
            if self._energy:
                w.write("electric_total_energy: %20.10f\n" % self._energy)
                
        w.write("status: %s\n" % self._status)
        w.write("tasks:\n")
        for task in self._phonon_tasks:
            if task and task.get_status():
                w.write("- name:   %s\n" % task.get_name())
                w.write("  status: %s\n" % task.get_status())
        w.close()
Exemple #59
0
from phonopy.file_IO import parse_FORCE_SETS

def append_band(bands, q_start, q_end):
    band = []
    for i in range(51):
        band.append(np.array(q_start) +
                    (np.array(q_end) - np.array(q_start)) / 50 * i)
    bands.append(band)

phonons = {}
for vol in ("orig", "plus", "minus"):
    unitcell = read_vasp("%s/POSCAR-unitcell" % vol)
    phonon = Phonopy(unitcell,
                     [[2, 0, 0],
                      [0, 2, 0],
                      [0, 0, 2]],
                     primitive_matrix=[[0, 0.5, 0.5],
                                       [0.5, 0, 0.5],
                                       [0.5, 0.5, 0]])
    force_sets = parse_FORCE_SETS(filename="%s/FORCE_SETS" % vol)
    phonon.set_displacement_dataset(force_sets)
    phonon.produce_force_constants()
    phonons[vol] = phonon

gruneisen = PhonopyGruneisen(phonons["orig"],
                             phonons["plus"],
                             phonons["minus"])

gruneisen.set_mesh([2, 2, 2])
q_points, _, frequencies, _, gammas = gruneisen.get_mesh()
for q, freq, g in zip(q_points, frequencies, gammas):
Exemple #60
0
class PhononFC3Base(TaskElement):
    """PhononFC3Base class

    This is an interface to anharmonic phonopy.

    """

    def __init__(self,
                 directory=None,
                 name=None,
                 supercell_matrix=None,
                 primitive_matrix=None,
                 distance=None,
                 is_diagonal=True,
                 check_imaginary=True,
                 cutoff_frequency=None,
                 lattice_tolerance=None,
                 force_tolerance=None,
                 pressure_target=None,
                 stress_tolerance=None,
                 max_increase=None,
                 max_iteration=None,
                 min_iteration=None,
                 is_cell_relaxed=False,
                 traverse=False):

        TaskElement.__init__(self)

        self._directory = directory
        if not name:
            self._name = directory
        else:
            self._name = name
        self._task_type = "anharmonic_phonon"
        self._supercell_matrix = supercell_matrix
        self._primitive_matrix = primitive_matrix
        self._distance = distance
        self._is_diagonal = is_diagonal
        self._check_imaginary = check_imaginary
        self._cutoff_frequency = cutoff_frequency # determine imaginary freq.
        self._lattice_tolerance = lattice_tolerance
        self._pressure_target = pressure_target
        self._stress_tolerance = stress_tolerance
        self._force_tolerance = force_tolerance
        self._max_increase = max_increase
        self._max_iteration = max_iteration
        self._min_iteration = min_iteration
        self._traverse = traverse
        self._is_cell_relaxed = is_cell_relaxed

        self._stage = 0
        self._tasks = []

        self._energy = None
        self._cell = None
        self._phonon = None # Phonopy object
        self._phonon_fc3 = None # Phono3py object
        self._phonon_fc3_tasks = None

    def get_phonon(self):
        return self._phonon

    def get_phonon_fc3(self):
        for i, task in enumerate(self._phonon_fc3_tasks[1:]):
            forces_fc3.append(task.get_properties()['forces'][-1])
        disp_dataset = self._phonon_fc3.get_displacement_dataset()
        self._phonon_fc3.produce_fc3(forces_fc3)

        return self._phonon_fc3

    def get_cell(self):
        if self._is_cell_relaxed:
            return self._cell
        else:
            return self._phonon_fc3_tasks[0].get_cell()

    def get_energy(self):
        """Return energies at geometry optimization steps"""
        return self._energy

    def set_status(self):
        if self._stage == 0:
            task = self._tasks[0]
            if task.done():
                status = task.get_status()
                if status == "done":
                    self._status = "next"
                else:
                    self._status = status
        else:
            done = True
            terminate = False
            for i, task in enumerate(self._tasks):
                done &= task.done()
                terminate |= (task.get_status() == "terminate")

            if done:
                if terminate:
                    self._status = "terminate"
                else:
                    self._status = "next"

        self._write_yaml()

    def begin(self):
        if not self._job:
            print("set_job has to be executed.")
            raise RuntimeError

        if self._is_cell_relaxed:
            self._phonon_fc3_tasks = [None]
            self._set_stage1()
        else:
            self._set_stage0()

    def end(self):
        pass

    def done(self):
        return (self._status == "terminate" or
                self._status == "done" or
                self._status == "max_iteration" or
                self._status == "next" or
                self._status == "imaginary_mode")

    def __next__(self):
        return self.next()

    def next(self):
        if self._stage == 0:
            if "next" in self._status:
                self._energy = self._tasks[0].get_energy()
                self._comment = "%s\\n%f" % (
                    self._tasks[0].get_space_group()['international'],
                    self._energy)
                self._set_stage1()
                return self._tasks
            elif "terminate" in self._status and self._traverse == "restart":
                self._traverse = False
                self._set_stage0()
                return self._tasks
            else:
                raise StopIteration
        elif self._stage == 1:
            if "next" in self._status:
                disp_dataset = self._phonon_fc3.get_displacement_dataset()
                for disp1, task in zip(disp_dataset['first_atoms'], self._tasks):
                    disp1['forces'] = task.get_properties()['forces'][-1]
                write_FORCE_SETS(disp_dataset)
                self._phonon.set_displacement_dataset(disp_dataset)
                self._phonon.produce_force_constants(
                    calculate_full_force_constants=False)
                if self._exist_imaginary_mode():
                    self._status = "imaginary_mode"
                    self._write_yaml()
                    self._tasks = []
                    raise StopIteration
                else:
                    self._set_stage2()
                    return self._tasks
            elif "terminate" in self._status and self._traverse == "restart":
                self._reset_stage1()
                return self._tasks
            else:
                raise StopIteration
        elif self._stage == 2:
            if "next" in self._status:
                self._status = "done"
                forces_fc3 = []
                for i, task in enumerate(self._phonon_fc3_tasks[1:]):
                    forces_fc3.append(task.get_properties()['forces'][-1])
                disp_dataset = self._phonon_fc3.get_displacement_dataset()
                write_FORCES_FC3(disp_dataset, forces_fc3)
                self._tasks = []
                raise StopIteration
            elif "terminate" in self._status and self._traverse == "restart":
                self._reset_stage2()
                return self._tasks
            else:
                raise StopIteration
        else: # stage2
            pass

    def _set_stage0(self):
        self._status = "equilibrium"
        task = self._get_equilibrium_task()
        self._phonon_fc3_tasks = [task]
        self._tasks = [task]

    def _set_stage1(self):
        self._set_phonon_fc3()
        if self._check_imaginary:
            self._stage = 1
            self._status = "fc2_displacements"
            disp_dataset = self._phonon_fc3.get_displacement_dataset()
            self._tasks = self._get_displacement_tasks(
                stop=len(disp_dataset['first_atoms']))
            self._phonon_fc3_tasks += self._tasks
        else:
            self._set_stage2()

    def _reset_stage1(self):
        self._traverse = False
        disp_terminated = []
        for i, task in enumerate(self._tasks):
            if task.get_status() == "terminate":
                disp_terminated.append(i)
        disp_dataset = self._phonon_fc3.get_displacement_dataset()
        tasks = self._get_displacement_tasks(
            stop=len(disp_dataset['first_atoms']))
        self._tasks = []
        for i in disp_terminated:
            self._tasks.append(tasks[i])
            self._phonon_fc3_tasks[i + 1] = tasks[i]
        self._status = "fc2_displacements"

    def _set_stage2(self):
        self._stage = 2
        self._status = "fc3_displacements"
        if self._check_imaginary:
            disp_dataset = self._phonon_fc3.get_displacement_dataset()
            start_index = len(disp_dataset['first_atoms'])
        else:
            start_index = 0
        self._tasks = self._get_displacement_tasks(start=start_index)
        self._phonon_fc3_tasks += self._tasks

    def _reset_stage2(self):
        self._traverse = False
        disp_terminated = []
        for i, task in enumerate(self._tasks):
            if task.get_status() == "terminate":
                disp_terminated.append(i)

        if self._check_imaginary:
            disp_dataset = self._phonon_fc3.get_displacement_dataset()
            start_index = len(disp_dataset['first_atoms'])
        else:
            start_index = 0
        tasks = self._get_displacement_tasks(start=start_index)
        self._tasks = []
        for i in disp_terminated:
            self._tasks.append(tasks[i])
            self._phonon_fc3_tasks[i + 1 + start_index] = tasks[i]
        self._status = "fc3_displacements"

    def _set_phonon_fc3(self):
        cell = self.get_cell()
        phonopy_cell = cell2atoms(cell)
        self._phonon = Phonopy(phonopy_cell,
                               self._supercell_matrix,
                               primitive_matrix=self._primitive_matrix,
                               dynamical_matrix_decimals=14,
                               force_constants_decimals=14)
        self._phonon_fc3 = Phono3py(phonopy_cell,
                                    self._supercell_matrix,
                                    primitive_matrix=self._primitive_matrix)
        self._phonon_fc3.generate_displacements(distance=self._distance,
                                                is_diagonal=self._is_diagonal)
        supercell = self._phonon_fc3.get_supercell()
        disp_dataset = self._phonon_fc3.get_displacement_dataset()
        self._phonon.set_displacement_dataset(disp_dataset)
        write_poscar(cell, "POSCAR-unitcell")
        write_disp_yaml(self._phonon.get_displacements(),
                        supercell,
                        directions=self._phonon.get_displacement_directions())
        write_disp_fc3_yaml(disp_dataset, supercell)

    def _exist_imaginary_mode(self):
        if self._primitive_matrix is None:
            pmat = np.eye(3)
        else:
            pmat = self._primitive_matrix
        exact_point_matrix = np.dot(np.linalg.inv(self._supercell_matrix),
                                    pmat).T
        max_integer = np.rint(np.amax(np.abs(np.linalg.inv(exact_point_matrix))))
        q_points = []
        for i in np.arange(-max_integer, max_integer + 1):
            for j in np.arange(-max_integer, max_integer + 1):
                for k in np.arange(-max_integer, max_integer + 1):
                    q = np.dot(exact_point_matrix, [i, j, k])
                    if (-1 < q).all() and (q < 1).all():
                        q_points.append(q)
        self._phonon.set_qpoints_phonon(q_points)
        frequencies = self._phonon.get_qpoints_phonon()[0]
        if (frequencies < self._cutoff_frequency).any():
            self._log = "Stop at phonon calculation due to imaginary modes"
            return True
        else:
            return False

    def _write_yaml(self):
        w = open("%s.yaml" % self._directory, 'w')
        if self._lattice_tolerance is not None:
            w.write("lattice_tolerance: %f\n" % self._lattice_tolerance)
        if self._stress_tolerance is not None:
            w.write("stress_tolerance: %f\n" % self._stress_tolerance)
            w.write("pressure_target: %f\n" % self._pressure_target)
        w.write("force_tolerance: %f\n" % self._force_tolerance)
        if self._max_increase is None:
            w.write("max_increase: unset\n")
        else:
            w.write("max_increase: %f\n" % self._max_increase)
        w.write("max_iteration: %d\n" % self._max_iteration)
        w.write("min_iteration: %d\n" % self._min_iteration)
        w.write("supercell_matrix:\n")
        for row in self._supercell_matrix:
            w.write("- [ %3d, %3d, %3d ]\n" % tuple(row))
        if self._primitive_matrix is not None:
            w.write("primitive_matrix:\n")
            for row in self._primitive_matrix:
                w.write("- [ %6.3f, %6.3f, %6.3f ]\n" % tuple(row))
        w.write("distance: %f\n" % self._distance)
        if self._phonon_fc3_tasks[0] is not None:
            w.write("iteration: %d\n" % self._phonon_fc3_tasks[0].get_stage())
            if self._energy:
                w.write("electric_total_energy: %20.10f\n" % self._energy)
        w.write("status: %s\n" % self._status)
        w.write("tasks:\n")
        for task in self._phonon_fc3_tasks:
            if task and task.get_status():
                w.write("- name:   %s\n" % task.get_name())
                w.write("  status: %s\n" % task.get_status())
        w.close()