Ejemplo n.º 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
Ejemplo n.º 2
0
def phonons(model, bulk, supercell, dx, mesh=None, points=None, n_points=50):

    import model

    unitcell = PhonopyAtoms(symbols=bulk.get_chemical_symbols(),
                            cell=bulk.get_cell(),
                            scaled_positions=bulk.get_scaled_positions())
    phonon = Phonopy(unitcell, supercell)
    phonon.generate_displacements(distance=dx)

    sets_of_forces = []

    for s in phonon.get_supercells_with_displacements():
        at = Atoms(cell=s.get_cell(),
                   symbols=s.get_chemical_symbols(),
                   scaled_positions=s.get_scaled_positions(),
                   pbc=3 * [True])
        at.set_calculator(model.calculator)
        sets_of_forces.append(at.get_forces())

    phonon.set_forces(sets_of_forces=sets_of_forces)
    phonon.produce_force_constants()

    properties = {}

    if mesh is not None:
        phonon.set_mesh(mesh, is_gamma_center=True)
        qpoints, weights, frequencies, eigvecs = phonon.get_mesh()

        properties["frequencies"] = frequencies.tolist()
        properties["weights"] = weights.tolist()

    if points is not None:
        bands = []
        for i in range(len(points) - 1):
            band = []
            for r in np.linspace(0, 1, n_points):
                band.append(points[i] + (points[i + 1] - points[i]) * r)
            bands.append(band)

        phonon.set_band_structure(bands,
                                  is_eigenvectors=True,
                                  is_band_connection=False)
        band_q_points, band_distances, band_frequencies, band_eigvecs = phonon.get_band_structure(
        )

        band_distance_max = np.max(band_distances)
        band_distances = [(_b / band_distance_max).tolist()
                          for _b in band_distances]

        band_frequencies = [_b.tolist() for _b in band_frequencies]

        properties["band_q_points"] = band_q_points
        properties["band_distances"] = band_distances
        properties["band_frequencies"] = band_frequencies
        properties["band_eigvecs"] = band_eigvecs

    properties["phonopy"] = phonon

    return properties
Ejemplo n.º 3
0
def do_phonons(strt=None, parameters=None, c_size=25):
    """
    Setting up phonopy job using LAMMPS

    Args:
        strt: Structure object
        parameters: LAMMPS input file parameters
        c_size: cell-size 
    
    """

    p = get_phonopy_atoms(mat=strt)
    bulk = p

    dim1 = int((float(c_size) / float(max(abs(strt.lattice.matrix[0]))))) + 1
    dim2 = int(float(c_size) / float(max(abs(strt.lattice.matrix[1])))) + 1
    dim3 = int(float(c_size) / float(max(abs(strt.lattice.matrix[2])))) + 1
    Poscar(strt).write_file("POSCAR")
    tmp = strt.copy()
    tmp.make_supercell([dim1, dim2, dim3])
    Poscar(tmp).write_file("POSCAR-Super.vasp")

    phonon = Phonopy(bulk, [[dim1, 0, 0], [0, dim2, 0], [0, 0, dim3]])  # ,
    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 = []
    disp = 0
    for scell in supercells:
        cell = Atoms(
            symbols=scell.get_chemical_symbols(),
            scaled_positions=scell.get_scaled_positions(),
            cell=scell.get_cell(),
            pbc=True,
        )
        disp = disp + 1

    mat = Poscar(AseAtomsAdaptor().get_structure(cell))
    mat.comment = str("disp-") + str(disp)
    parameters["min"] = "skip"
    parameters["control_file"] = "/users/knc6/in.phonon"
    # a,b,forces=run_job(mat=mat,parameters={'min':'skip','pair_coeff': '/data/knc6/JARVIS-FF-NEW/ALLOY4/Mishin-Ni-Al-2009.eam.alloy', 'control_file': '/users/knc6/in.phonon', 'pair_style': 'eam/alloy', 'atom_style': 'charge'})
    a, b, forces = run_job(mat=mat, parameters=parameters)
    print("forces=", forces)
    drift_force = forces.sum(axis=0)
    print("drift forces=", drift_force)
    print("[Phonopy] Drift force:", "%11.5f" * 3 % tuple(drift_force))
    # Simple translational invariance
    for force in forces:
        force -= drift_force / forces.shape[0]
    set_of_forces.append(forces)
    phonon.produce_force_constants(forces=set_of_forces)

    write_FORCE_CONSTANTS(phonon.get_force_constants(), filename="FORCE_CONSTANTS")
    print()
    print("[Phonopy] Phonon frequencies at Gamma:")
Ejemplo n.º 4
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
Ejemplo n.º 5
0
def create_supercells_with_displacements_using_phonopy(structure, ph_settings):
    """
    Use phonopy to create the supercells with displacements to calculate the force constants by using
    finite displacements methodology

    :param structure: StructureData object
    :param phonopy_input: ParametersData object containing a dictionary with the data needed for phonopy
    :return: A set of StructureData Objects containing the supercells with displacements
    """
    from phonopy import Phonopy

    # Generate phonopy phonon object
    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)

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

    cells_with_disp = phonon.get_supercells_with_displacements()

    # Transform cells to StructureData and set them ready to return
    data_sets = phonon.get_displacement_dataset()
    data_sets_object = ForceSetsData(data_sets=data_sets)

    disp_cells = {'data_sets': data_sets_object}
    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
Ejemplo n.º 6
0
def get_displaced_structures(pmg_structure,
                             atom_disp=0.01,
                             supercell_matrix=None,
                             yaml_fname=None,
                             **kwargs):
    r"""
    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()
        write_disp_yaml(
            displacements=displacements,
            supercell=phonon.get_supercell(),
            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
Ejemplo n.º 7
0
def do_phonons(strt=None,parameters=None):

        p= get_phonopy_atoms(mat=strt)
        bulk =p
        c_size=parameters['phon_size']
        dim1=int((float(c_size)/float( max(abs(strt.lattice.matrix[0])))))+1
        dim2=int(float(c_size)/float( max(abs(strt.lattice.matrix[1]))))+1
        dim3=int(float(c_size)/float( max(abs(strt.lattice.matrix[2]))))+1
        Poscar(strt).write_file("POSCAR")
        tmp=strt.copy()
        tmp.make_supercell([dim1,dim2,dim3])
        Poscar(tmp).write_file("POSCAR-Super.vasp")
    
        print ('supercells',dim1,dim2,dim3)
        phonon = Phonopy(bulk,[[dim1,0,0],[0,dim2,0],[0,0,dim3]]) 
        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 = []
        disp=0
        for scell in supercells:
            cell = Atoms(symbols=scell.get_chemical_symbols(),
                         scaled_positions=scell.get_scaled_positions(),
                         cell=scell.get_cell(),
                         pbc=True)
            disp=disp+1

            mat = Poscar(AseAtomsAdaptor().get_structure(cell))
            mat.comment=str("disp-")+str(disp)
            parameters['min']='skip'
            parameters['control_file']= parameters['phonon_control_file']  #'/users/knc6/in.phonon'
            #a,b,forces=run_job(mat=mat,parameters={'min':'skip','pair_coeff': '/data/knc6/JARVIS-FF-NEW/ALLOY4/Mishin-Ni-Al-2009.eam.alloy', 'control_file': '/users/knc6/in.phonon', 'pair_style': 'eam/alloy', 'atom_style': 'charge'})
            a,b,forces=run_job(mat=mat,parameters=parameters)
            #print "forces=",forces
            drift_force = forces.sum(axis=0)
            #print "drift forces=",drift_force
            #print "[Phonopy] Drift force:", "%11.5f"*3 % tuple(drift_force)
            # Simple translational invariance
            for force in forces:
                force -= drift_force / forces.shape[0]
            set_of_forces.append(forces)
        phonon.produce_force_constants(forces=set_of_forces)

        write_FORCE_CONSTANTS(phonon.get_force_constants(),
                              filename="FORCE_CONSTANTS")
        #print
        #print "[Phonopy] Phonon frequencies at Gamma:"
        for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))):
            print ("[Phonopy] %3d: %10.5f THz" %  (i + 1, freq)) # THz
Ejemplo n.º 8
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
Ejemplo n.º 9
0
def _calc_quick(atoms, supercell=(1, 1, 1), delta=0.01):
    """Calculates the Hessian for a given atoms object just like :func:`calc`,
    *but*, it uses symmetry to speed up the calculation. Depending on the
    calculator being used, it is possible that the symmetrized result may be
    different from the full result with all displacements, done manually by
    :func:`calc`.

    Args:
        atoms (matdb.atoms.Atoms): atomic structure of the *primitive*.
        supercell (list): or `tuple` or :class:`numpy.ndarray` specifying the
          integer supercell matrix.
        delta (float): displacement in Angstroms of each atom when computing the
          phonons. 

    Returns:
        numpy.ndarray: Hessian matrix that has dimension `(natoms*3, natoms*3)`,
        where `natoms` is the number of atoms in the *supercell*.
    """
    #We need to make sure we are at the zero of the potential before
    ratoms = atoms.copy()
    try:
        with open("phonons.log", 'w') as f:
            with redirect_stdout(f):
                print(ratoms.get_forces())
                minim = FIRE(ratoms)
                minim.run(fmax=1e-4, steps=100)
    except:
        #The potential is unstable probably. Issue a warning.
        msg.warn(
            "Couldn't optimize the atoms object. Potential may be unstable.")

    primitive = matdb_to_phonopy(ratoms)
    phonon = Phonopy(primitive, conform_supercell(supercell))
    phonon.generate_displacements(distance=delta)
    supercells = phonon.get_supercells_with_displacements()
    pot = atoms.get_calculator()
    assert pot is not None

    forces = []
    for scell in supercells:
        matoms = phonopy_to_matdb(scell)
        #Call a manual reset of the calculator so that we explicitly recalculate
        #the forces for the current atoms object.
        pot.reset()
        matoms.set_calculator(pot)
        forces.append(matoms.get_forces())

    phonon.set_forces(forces)
    phonon.produce_force_constants()
    return unroll_fc(phonon._force_constants)
Ejemplo n.º 10
0
def create_supercells_with_displacements_using_phonopy(structure,
                                                       phonopy_input):
    """
    Create the supercells with the displacements to use the finite displacements methodology to calculate the
    force constants
    :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 displacement distance.
    :return: dictionary of Aiida StructureData Objects containing the cells with displacements
    """
    from phonopy.structure.atoms import Atoms as PhonopyAtoms
    from phonopy import Phonopy
    import numpy as np

    # 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()
    phonon = Phonopy(bulk,
                     phonopy_input['supercell'],
                     primitive_matrix=phonopy_input['primitive'])

    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
    data_sets = phonon.get_displacement_dataset()
    data_sets_object = ArrayData()
    for i, first_atoms in enumerate(data_sets['first_atoms']):
        data_sets_array = np.array([
            first_atoms['direction'], first_atoms['number'],
            first_atoms['displacement']
        ])
        data_sets_object.set_array('data_sets_{}'.format(i), data_sets_array)

    disp_cells = {'data_sets': data_sets_object}
    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
Ejemplo n.º 11
0
    def _get_phononobject_phonopy(self,
                                  structure,
                                  potential,
                                  smat,
                                  save_parameters,
                                  path,
                                  displacement_distance=0.01):
        cell = get_phonopy_structure(structure)
        phonon = Phonopy(cell,
                         smat,
                         primitive_matrix=[[1.0, 0.0, 0.0], [0.0, 1, 0.0],
                                           [0., 0., 1.0]],
                         factor=VaspToTHz)

        # displacements
        phonon.generate_displacements(distance=displacement_distance)
        print("[Phonopy] Atomic displacements:")
        disps = phonon.get_displacements()
        for d in disps:
            print("[Phonopy] %d %s" % (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)
            cell.set_calculator(potential)
            # this part is adapted from: https://web.archive.org/web/20200610084959/https://github.com/phonopy/phonopy/blob/develop/example/ase/8Si-phonon.py
            # Copyright by Atsushi Togo
            forces = cell.get_forces()
            drift_force = forces.sum(axis=0)
            print(
                ("[Phonopy] Drift force:" + "%11.5f" * 3) % tuple(drift_force))
            for force in forces:
                force -= drift_force / forces.shape[0]
            set_of_forces.append(forces)

        phonon.produce_force_constants(forces=set_of_forces)
        if save_parameters:
            phonon.save(path)
        return phonon
Ejemplo n.º 12
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:
        phonon.generate_displacements(distance=disp)
        supercells = phonon.get_supercells_with_displacements()

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

            at.set_calculator(calc)

            energy = at.get_potential_energy(force_consistent=True)
            forces = at.get_forces()
            stress = at.get_stress(voigt=False)

            drift_force = forces.sum(axis=0)
            print(("[Phonopy] Drift force:" + "%11.5f" * 3) %
                  tuple(drift_force))
            # Simple translational invariance
            for force in forces:
                force -= drift_force / forces.shape[0]
            at.arrays["force"] = forces
            at.info["virial"] = -1.0 * at.get_volume() * stress
            at.info["energy"] = energy
            at.info["config_type"] = "PH_" + config_type
            write("PH_{}_{}_scell_{}.xyz".format(config_type, i, disp), at)
            al.append(at)

    return al
Ejemplo n.º 13
0
class PhononFromModel(object):
    """
    This class uses frozen phonon method to calculate the phonon dispersion curves and thermodynamic
    properties of a structure.
    The steps are as follows:
        1. Displaced structures are obtained from pristine structure via phonopy.
        2. The forces of each displaced structures are calculated by model
        3. The forces are passed to phonopy object and the force constant are produced
        4. Phonon is calculated once the force constant matrix is available.

    Args:
        model (model object): a model object that has a method "calculate_forces" that takes in a list of
            structures and return a list of N*3 forces, where N are the number of atoms in each structures
        structure (pymatgen structure): a pristine pymatgen structure
        atom_disp (float): small displacements in Angstrom

    """

    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 get_thermo_properties(self, mesh=[8, 8, 8], t_step=10, t_max=3000, t_min=0):
        self.phonon.set_mesh(mesh=mesh)
        self.phonon.set_thermal_properties(t_step=t_step,
                                           t_max=t_max,
                                           t_min=t_min)
        plt = self.phonon.plot_thermal_properties()
        return plt

    def get_bs_plot(self, points_per_line=50, figsize=(6, 4), ylim=[-1, 5]):
        bands = []
        bands = append_bands(bands, self.qpoints, points_per_line)
        self.phonon.set_band_structure(bands)
        q_points, self.distances, self.frequencies, eigvecs = self.phonon.get_band_structure()

        special_points = self.phonon._band_structure._special_points
        distance = self.phonon._band_structure._distance

        plt.figure(figsize=figsize)
        for j, (d, f) in enumerate(zip(self.distances, self.frequencies)):
            for i, freqs in enumerate(f.T):
                if i == 0 and j == 0:
                    plt.plot(d, freqs, "b-", lw=1)
                else:
                    plt.plot(d, freqs, "b-", lw=1)
        for sp in special_points:
            plt.axvline(x=sp, linestyle=':', linewidth=1, color='k')
        plt.axhline(y=0, linestyle=':', linewidth=1, color='k')

        plt.xticks(special_points, ["$\mathrm{%s}$" % i for i in self.vertices])
        plt.xlabel("Wave vector")
        plt.ylabel("Frequency (THz)")
        plt.xlim(0, distance)
        plt.ylim(ylim)
        plt.yticks(list(range(ylim[0], ylim[-1]+1)))
        plt.tight_layout()
        return plt
Ejemplo n.º 14
0
def get_phonon_distrib_alist(
    prim_cell,
    NNN,
    T,
    seed_range,
    calc,
    cp_files=None,
    plus_minus=True,
    delta=0.01,
    ):
    """
    prim_cell (str)
        ASE readable primitive unitcell structure file.
    NNN (list of int, shape: (3,3))
        Supercell matrix used to calculate force constants.
    T (float)
        Temperature in Kelvin unit.
    seed_range (range or list of int)
        Seeds for random number generation.
    calc (str, choices: ('lmp', 'vasp'))
        Calculator for force calculation.
    cp_files (list of str)
        List of input files for force calculation.
    plus_minus (bool)
        Option handed to ASE function.
    delta (float)
        Displacement in Angstrom for finite displacement method.
    """

    # Main
    from ase.io import read, write
    atoms = read(prim_cell)
    from phonopy import Phonopy
    phonon = Phonopy(
        atoms,
        NNN,
        )
    phonon.generate_displacements(
        delta,
        )
    pho_super = phonon.get_supercell()
    pho_disp  = phonon.get_supercells_with_displacements()
    from phonopy.interface import vasp
    vasp.write_supercells_with_displacements(
        pho_super,
        pho_disp,
        )
    import ss_phonopy as ssp
    phonon = ssp.calc_phonon(
        calc,
        phonon,
        cp_files=cp_files,
        )
    masses = pho_super.masses
    job_name = 'eig_x{}{}{}_d{:5.3f}_sym{}'.format(NNN[0][0], NNN[1][1], NNN[2][2], delta, phonon._is_symmetry)
    try:
        e_s = np.load('{}.npz'.format(job_name))
    except:
        print('Failed to load {}.npz file. Start to solve eigen problem.'.format(job_name))
        eigen_set = get_eigen_set(
            phonon.get_force_constants(),
            masses,
            )
        np.savez('{}.npz'.format(job_name), w2=eigen_set[0], D=eigen_set[1])
    else:
        print('Successfully loaded {}.npz file!'.format(job_name))
        eigen_set = (e_s['w2'], e_s['D'])

    from ase.md.velocitydistribution import phonon_harmonics
    from ase import Atoms, units
    alist = []
    for i in seed_range:
        d_ac, v_ac = phonon_harmonics(
            None,
            masses,
            T *units.kB,
            eigen_set=eigen_set,
            # rng=np.random.rand,
            seed=i,
            quantum=True,
            plus_minus=plus_minus,
            # return_eigensolution=False,
            # failfast=True,
            )
        new_super = Atoms(
            cell       = pho_super.get_cell(),
            symbols    = pho_super.get_chemical_symbols(),
            positions  = pho_super.get_positions() + d_ac,
            velocities = v_ac,
            pbc        = True,
            )
        alist.append(new_super)
    return(alist)
Ejemplo n.º 15
0
    relax.run(fmax=fmax)
    Unit_cell = api_ph.aseAtoms_to_phonopyAtoms(ucell_ase)
    Intf_vasp.write_vasp('POSCAR_relx', Unit_cell)

else:
    Unit_cell = Intf_vasp.read_vasp(
        "POSCAR")  # read prim cell from the POSCAR file

# generate displacements

prim_mat = np.eye(3)  #[[0, 0.5, 0.5],[0.5, 0, 0.5],[0.5, 0.5, 0]]
phonon_scell = Phonopy(
    Unit_cell, np.diag(Ncells),
    primitive_matrix=prim_mat)  # generate an phononpy object for LD calc.
phonon_scell.generate_displacements(distance=0.03)  # vasp
Scells_phonopy = phonon_scell.get_supercells_with_displacements(
)  # This returns a list of Phononpy atoms object

# convert phonopy atoms objects to quippy atom objects
Scells_quippy = []
for scell in Scells_phonopy:
    scell_qp = api_ph.phonopyAtoms_to_aseAtoms(scell)
    Scells_quippy.append(scell_qp)

# calculate forces and convert to phonopy force_sets
force_gap_scells = api_q.calc_force_sets_GAP(gp_xml_file, Scells_quippy)

#parse force set and calc force constants
phonon_scell.set_forces(force_gap_scells)
PhonIO.write_FORCE_SETS(phonon_scell.get_displacement_dataset()
                        )  # write forces & displacements to FORCE_SET
force_set = PhonIO.parse_FORCE_SETS()  # parse force_sets
Ejemplo n.º 16
0
    def phonons(self,
                atoms=None,
                lammps_cmd="",
                enforce_c_size=15.0,
                parameters={}):
        """Make Phonon calculation setup."""
        from phonopy import Phonopy
        from phonopy.file_IO import (
            #    parse_FORCE_CONSTANTS,
            write_FORCE_CONSTANTS, )

        bulk = atoms.phonopy_converter()

        dim = get_supercell_dims(atoms, enforce_c_size=enforce_c_size)
        atoms = atoms.make_supercell([dim[0], dim[1], dim[2]])

        Poscar(atoms).write_file("POSCAR")

        atoms = atoms.make_supercell_matrix([dim[0], dim[1], dim[2]])
        Poscar(atoms).write_file("POSCAR-Super.vasp")

        phonon = Phonopy(bulk,
                         [[dim[0], 0, 0], [0, dim[1], 0], [0, 0, dim[2]]])
        print("[Phonopy] Atomic displacements1:", bulk)
        print("[Phonopy] Atomic displacements2:", phonon, dim[0], dim[1],
              dim[2])
        phonon.generate_displacements(distance=0.03)
        disps = phonon.get_displacements()
        print("[Phonopy] Atomic displacements3:", disps)
        for d in disps:
            print("[Phonopy]", d[0], d[1:])
        supercells = phonon.get_supercells_with_displacements()

        # Force calculations by calculator
        set_of_forces = []
        disp = 0
        from ase import Atoms as AseAtoms

        for scell in supercells:
            ase_atoms = AseAtoms(
                symbols=scell.get_chemical_symbols(),
                scaled_positions=scell.get_scaled_positions(),
                cell=scell.get_cell(),
                pbc=True,
            )
            j_atoms = ase_to_atoms(ase_atoms)
            disp = disp + 1

            parameters["control_file"] = "run0.mod"
            a, b, forces = LammpsJob(
                atoms=j_atoms,
                lammps_cmd=lammps_cmd,
                parameters=parameters,
                jobname="disp-" + str(disp),
            ).runjob()
            print("forces=", forces)
            drift_force = forces.sum(axis=0)
            print("drift forces=", drift_force)
            # Simple translational invariance
            for force in forces:
                force -= drift_force / forces.shape[0]
            set_of_forces.append(forces)
        phonon.produce_force_constants(forces=set_of_forces)

        write_FORCE_CONSTANTS(phonon.get_force_constants(),
                              filename="FORCE_CONSTANTS")
        print()
        print("[Phonopy] Phonon frequencies at Gamma:")
Ejemplo n.º 17
0
def calculate_phonon(atoms,
                     calc,
                     ndim=np.eye(3),
                     primitive_matrix=np.eye(3),
                     distance=0.01,
                     factor=VaspToTHz,
                     is_symmetry=True,
                     symprec=1e-5,
                     func=None,
                     **func_args):
    """
    """
    if 'magmoms' in atoms.arrays:
        is_mag = True
    else:
        is_mag = False
    # 1. get displacements and supercells
    atoms.set_calculator(calc)
    # bulk = PhonopyAtoms(atoms=atoms)
    if is_mag:
        bulk = PhonopyAtoms(
            symbols=atoms.get_chemical_symbols(),
            scaled_positions=atoms.get_scaled_positions(),
            cell=atoms.get_cell(),
            magmoms=atoms.arrays['magmoms'],
        )
    else:
        bulk = PhonopyAtoms(symbols=atoms.get_chemical_symbols(),
                            scaled_positions=atoms.get_scaled_positions(),
                            cell=atoms.get_cell())

    phonon = Phonopy(bulk,
                     ndim,
                     primitive_matrix=primitive_matrix,
                     factor=factor,
                     symprec=symprec)
    phonon.generate_displacements(distance=distance)
    disps = phonon.get_displacements()
    for d in disps:
        print("[phonopy] %d %s" % (d[0], d[1:]))
    supercell0 = phonon.get_supercell()
    supercells = phonon.get_supercells_with_displacements()
    write_supercells_with_displacements(supercell0, supercells)
    write_disp_yaml(disps, supercell0)

    # 2. calculated forces.
    set_of_forces = []
    for iscell, scell in enumerate(supercells):
        cell = Atoms(symbols=scell.get_chemical_symbols(),
                     scaled_positions=scell.get_scaled_positions(),
                     cell=scell.get_cell(),
                     pbc=True)
        if is_mag:
            cell.set_initial_magnetic_moments(
                atoms.get_initial_magnetic_moments())
        cell.set_calculator(calc)
        dir_name = "PHON_CELL%s" % iscell
        cur_dir = os.getcwd()
        if not os.path.exists(dir_name):
            os.mkdir(dir_name)
        os.chdir(dir_name)
        forces = cell.get_forces()
        #print "[Phonopy] Forces: %s" % forces
        # Do something other than calculating the forces with func.
        # func: func(atoms, calc, func_args)
        if func is not None:
            func(cell, calc, **func_args)
        os.chdir(cur_dir)
        drift_force = forces.sum(axis=0)
        #print "[Phonopy] Drift force:", "%11.5f" * 3 % tuple(drift_force)
        # Simple translational invariance
        for force in forces:
            force -= drift_force / forces.shape[0]
        set_of_forces.append(forces)

    # Phonopy post-process
    phonon.produce_force_constants(forces=set_of_forces)
    force_constants = phonon.get_force_constants()
    write_FORCE_CONSTANTS(force_constants, filename='FORCE_CONSTANTS')
    print('')
    print("[Phonopy] Phonon frequencies at Gamma:")
    for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))):
        print("[Phonopy] %3d: %10.5f THz" % (i + 1, freq))  # THz
        print("[Phonopy] %3d: %10.5f cm-1" % (i + 1, freq * 33.35))  #cm-1
    return phonon
Ejemplo n.º 18
0
def calculate_phonon(atoms,
                     calc=None,
                     forces_set_file=None,
                     ndim=np.eye(3),
                     primitive_matrix=np.eye(3),
                     distance=0.01,
                     factor=VaspToTHz,
                     is_plusminus='auto',
                     is_symmetry=True,
                     symprec=1e-5,
                     func=None,
                     prepare_initial_wavecar=False,
                     skip=None,
                     restart=True,
                     parallel=True,
                     sc_mag=None,
                     **func_args):
    """
    """
    if 'magmoms' in atoms.arrays or 'initial_magmoms' in atoms.arrays:
        is_mag = True
    else:
        is_mag = False
    print("is_mag: ", is_mag)
    # 1. get displacements and supercells
    if calc is not None:
        atoms.set_calculator(calc)
    # bulk = PhonopyAtoms(atoms=atoms)
    if is_mag:
        bulk = PhonopyAtoms(
            symbols=atoms.get_chemical_symbols(),
            scaled_positions=atoms.get_scaled_positions(),
            cell=atoms.get_cell(),
            magmoms=atoms.arrays['initial_magmoms'],
        )
    else:
        bulk = PhonopyAtoms(symbols=atoms.get_chemical_symbols(),
                            scaled_positions=atoms.get_scaled_positions(),
                            cell=atoms.get_cell())

    phonon = Phonopy(bulk,
                     ndim,
                     primitive_matrix=primitive_matrix,
                     factor=factor,
                     symprec=symprec)
    phonon.generate_displacements(distance=distance, is_plusminus=is_plusminus)
    disps = phonon.get_displacements()
    for d in disps:
        print(("[phonopy] %d %s" % (d[0], d[1:])))
    supercell0 = phonon.get_supercell()
    supercells = phonon.get_supercells_with_displacements()
    #write_supercells_with_displacements(supercell0, supercells)
    write_disp_yaml(disps, supercell0)

    # 2. calculated forces.
    if forces_set_file is not None:
        symmetry = phonon.get_symmetry()
        set_of_forces = parse_FORCE_SETS(
            is_translational_invariance=False,
            filename=forces_set_file)  # ['first_atoms']
        # set_of_forces=np.array(set_of_forces)
        #set_of_forces=[np.asarray(f) for f in set_of_forces]
        phonon.set_displacement_dataset(set_of_forces)
        phonon.produce_force_constants()
    else:
        # initialize set of forces
        if restart and os.path.exists('forces_set.pickle'):
            try:
                with open("forces_set.pickle", 'rb') as myfile:
                    set_of_forces = pickle.load(myfile)
                iskip = len(set_of_forces) - 1
            except:
                set_of_forces = []
                iskip = -1
        else:
            set_of_forces = []
            iskip = -1

        if prepare_initial_wavecar and skip is None:
            scell = supercell0
            cell = Atoms(symbols=scell.get_chemical_symbols(),
                         scaled_positions=scell.get_scaled_positions(),
                         cell=scell.get_cell(),
                         pbc=True)
            if is_mag:
                cell.set_initial_magnetic_moments(sc_mag)
            write('Supercell.cif', cell)
            mcalc = copy.deepcopy(calc)
            mcalc.set(lwave=True, lcharg=True)
            cell.set_calculator(mcalc)
            dir_name = "SUPERCELL0"
            cur_dir = os.getcwd()
            if not os.path.exists(dir_name):
                os.mkdir(dir_name)
            os.chdir(dir_name)
            mcalc.scf_calculation(cell)
            os.chdir(cur_dir)

        def calc_force(iscell):
            scell = supercells[iscell]
            cell = Atoms(symbols=scell.get_chemical_symbols(),
                         scaled_positions=scell.get_scaled_positions(),
                         cell=scell.get_cell(),
                         pbc=True)
            if is_mag:
                cell.set_initial_magnetic_moments(sc_mag)
            cell.set_calculator(copy.deepcopy(calc))
            dir_name = "PHON_CELL%s" % iscell
            cur_dir = os.getcwd()
            if not os.path.exists(dir_name):
                os.mkdir(dir_name)
            if prepare_initial_wavecar:
                os.system('ln -s %s %s' %
                          (os.path.abspath("SUPERCELL0/WAVECAR"),
                           os.path.join(dir_name, 'WAVECAR')))

            os.chdir(dir_name)
            forces = cell.get_forces()
            print("[Phonopy] Forces: %s" % forces)
            # Do something other than calculating the forces with func.
            # func: func(atoms, calc, func_args)
            if func is not None:
                func(cell, calc, **func_args)
            os.chdir(cur_dir)
            drift_force = forces.sum(axis=0)
            print("[Phonopy] Drift force:", "%11.5f" * 3 % tuple(drift_force))
            # Simple translational invariance
            for force in forces:
                force -= drift_force / forces.shape[0]
            return forces

        if parallel:
            p = Pool()
            set_of_forces = p.map(calc_force,
                                  list(range(iskip, len(supercells))))
        else:
            for iscell, scell in enumerate(supercells):
                if iscell > iskip:
                    fs = calc_force(iscell)
                    set_of_forces.append(fs)
                    with open("forces_set.pickle", 'wb') as myfile:
                        pickle.dump(set_of_forces, myfile)

        phonon.produce_force_constants(forces=np.array(set_of_forces))
    force_constants = phonon.get_force_constants()
    write_FORCE_CONSTANTS(force_constants, filename='FORCE_CONSTANTS')
    #print("[Phonopy] Phonon frequencies at Gamma:")
    # for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))):
    #    print(("[Phonopy] %3d: %10.5f THz" % (i + 1, freq)))  # THz
    #    print(("[Phonopy] %3d: %10.5f cm-1" % (i + 1, freq * 33.35)))  #cm-1
    with open('phonon.pickle', 'wb') as myfile:
        pickle.dump(phonon, myfile)
    phonon.save(settings={'force_constants': True})
    return phonon
Ejemplo n.º 19
0
phonon = Phonopy(
    atoms,
    # [[N,0,0],[0,N,0],[0,0,N]],
    NNN,
    # primitive_matrix = [[0.5,0.5,0],[0,0.5,0.5],[0.5,0,0.5]],
    primitive_matrix=primitive_matrix,
    nac_params=nac_params,
    factor=factor,
    is_symmetry=is_symmetry,
)
phonon.generate_displacements(
    distance=delta,
    is_plusminus=is_plusminus,
)

pho_disp = phonon.get_supercells_with_displacements()

vasp.write_supercells_with_displacements(
    phonon.get_supercell(),
    pho_disp,
)

######### get new phonon object ##########
#
import ss_phonopy as ssp
phonon = ssp.calc_phonon(
    calc,
    phonon,
    acoustic_sum_rule=acou_sum_rule,
    rot_sum_rule=rot_sum_rule,
    r_cut=r_cut,
Ejemplo n.º 20
0
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)
    cell.set_calculator(calc)
    forces = cell.get_forces()
    drift_force = forces.sum(axis=0)
    print "[Phonopy] Drift force:", "%11.5f"*3 % tuple(drift_force)
    # Simple translational invariance
    for force in forces:
        force -= drift_force / forces.shape[0]