Exemplo n.º 1
0
def get_nac_params(
    primitive=None,
    nac_params=None,
    born_filename=None,
    is_nac=True,
    nac_factor=None,
    log_level=0,
):
    """Look for and return NAC parameters."""
    if born_filename is not None:
        _nac_params = parse_BORN(primitive, filename=born_filename)
        if log_level:
            print('NAC parameters were read from "%s".' % born_filename)
    elif nac_params is not None:  # nac_params input or phonopy_yaml.nac_params
        _nac_params = nac_params
    elif is_nac and os.path.isfile("BORN"):
        _nac_params = parse_BORN(primitive, filename="BORN")
        if log_level:
            print('NAC params were read from "BORN".')
    else:
        _nac_params = None

    if _nac_params is not None:
        if "factor" not in _nac_params or _nac_params["factor"] is None:
            _nac_params["factor"] = nac_factor

    return _nac_params
Exemplo n.º 2
0
def set_nac_params(phonon, nac_params, born_filename, is_nac, nac_factor):
    _nac_params = None
    if nac_params is not None:
        _nac_params = nac_params
    elif born_filename is not None:
        _nac_params = parse_BORN(phonon.primitive, filename=born_filename)
    elif is_nac is True:
        if os.path.isfile("BORN"):
            _nac_params = parse_BORN(phonon.primitive, filename="BORN")

    if _nac_params is not None:
        if _nac_params['factor'] is None:
            _nac_params['factor'] = nac_factor
        phonon.nac_params = _nac_params
Exemplo n.º 3
0
def get_phonon(structure, NAC=False, setup_forces=True, custom_supercell=None):

    super_cell_phonon = structure.get_supercell_phonon()
    if not(isinstance(custom_supercell, type(None))):
        super_cell_phonon = custom_supercell

    #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, super_cell_phonon,
                     primitive_matrix=structure.get_primitive_matrix())

    # 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)

    if setup_forces:
        if not structure.forces_available():
    #    if not np.array(structure.get_force_constants()).any() and not np.array(structure.get_force_sets()).any():
            print('No force sets/constants available!')
            exit()
        if np.array(structure.get_force_constants()).any():
            phonon.set_force_constants(structure.get_force_constants())
        else:
            phonon.set_displacement_dataset(structure.get_force_sets())
            phonon.produce_force_constants(computation_algorithm="svd")

    return phonon
Exemplo n.º 4
0
def get_phonon(structure, NAC=False):

    force_atoms_file = structure.get_force_set()['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(structure.get_force_set())
    phonon.produce_force_constants(computation_algorithm="svd")


    return phonon
Exemplo n.º 5
0
def ReadBORN(structure, filePath="BORN"):
    """
    Read a Phonopy BORN file, and expand the charges for the supplied structure, and return a list of Born effective-charge tensors for each atom in the structure.

    Arguments:
        structure -- a tuple of (lattice_vectors, atomic_symbols, atom_positions) specifying the structure to be used to expand the Born charges to the full set of atoms.

    Keyword arguments:
        filePath -- path to the Phonopy BORN-format file to read (default: BORN).

    Return value:
        A list of 3x3 Born effective-charge tensors for each atom in the supplied structure.

    Notes:
        The atom positions supplied with structure are assumed to be in fractional coordinates.
    """

    # Convert the supplied structure to a Phonopy Atoms object.

    latticeVectors, atomicSymbols, atomPositions = structure

    cell = Atoms(symbols=atomicSymbols,
                 cell=latticeVectors,
                 scaled_positions=atomPositions)

    # Read the BORN file.

    bornData = parse_BORN(cell, filename=filePath)

    # Return the Born effective-charge tensors from the dictionary returned by parse_BORN.

    return [becTensor for becTensor in bornData['born']]
Exemplo n.º 6
0
    def get_phonons(self):
        """
        Calculate the phonon bandstructures along a path
        """
        phonon = self.phonon

        #get forces
        force_sets = file_IO.parse_FORCE_SETS(filename='%s/FORCE_SETS' %
                                              self.material_id)
        phonon.set_displacement_dataset(force_sets)

        #get force constants
        phonon.produce_force_constants()
        phonon.symmetrize_force_constants_by_space_group()

        #get NAC
        nac_params = file_IO.parse_BORN(phonon.get_primitive(),
                                        filename="%s/BORN" % self.material_id)
        nac_factor = Hartree * Bohr
        if nac_params['factor'] == None:
            nac_params['factor'] = nac_factor
        phonon.set_nac_params(nac_params)

        #get band-structure
        phonon.set_band_structure(self.bands,
                                  is_eigenvectors=True,
                                  is_band_connection=True)
        phonon.get_band_structure()
Exemplo n.º 7
0
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
Exemplo n.º 8
0
def get_phonon(structure,
               NAC=False,
               setup_forces=True,
               super_cell_phonon=np.identity(3),
               primitive_axis=np.identity(3)):

    phonon = Phonopy(structure, super_cell_phonon,
                     primitive_matrix=primitive_axis,
                     symprec=1e-5)

    # Non Analytical Corrections (NAC) from Phonopy [Frequencies only, eigenvectors no affected by this option]

    if setup_forces:
        if structure.get_force_constants() is not None:
            phonon.set_force_constants(structure.get_force_constants().get_array())
        elif structure.get_force_sets() is not None:
            phonon.set_displacement_dataset(structure.get_force_sets().get_dict())
            phonon.produce_force_constants(computation_algorithm="svd")
            structure.set_force_constants(ForceConstants(phonon.get_force_constants(),
                                                         supercell=structure.get_force_sets().get_supercell()))
        else:
            print('No force sets/constants available!')
            exit()

    if NAC:
        print("Using non-analytical corrections")
        primitive = phonon.get_primitive()
        nac_params = parse_BORN(primitive, is_symmetry=True)
        phonon.set_nac_params(nac_params=nac_params)

    return phonon
Exemplo n.º 9
0
def _set_nac_params(phonon, nac_params, born_filename, is_nac, nac_factor):
    if nac_params is not None:
        _nac_params = nac_params
    elif born_filename is not None:
        _nac_params = parse_BORN(phonon.primitive, filename=born_filename)
    elif is_nac is True:
        if os.path.isfile("BORN"):
            _nac_params = parse_BORN(phonon.primitive, filename="BORN")
        else:
            raise RuntimeError("BORN file doesn't exist at current directory.")
    else:
        _nac_params = None

    if _nac_params is not None:
        if _nac_params['factor'] is None:
            _nac_params['factor'] = nac_factor
        phonon.set_nac_params(_nac_params)
Exemplo n.º 10
0
def load(supercell_matrix,
         primitive_matrix=None,
         nac_params=None,
         unitcell=None,
         calculator="vasp",
         unitcell_filename=None,
         born_filename=None,
         force_sets_filename=None,
         force_constants_filename=None,
         factor=VaspToTHz,
         frequency_scale_factor=None,
         symprec=1e-5,
         is_symmetry=True,
         log_level=0):

    if unitcell is None:
        _unitcell, _ = read_crystal_structure(filename=unitcell_filename,
                                              interface_mode=calculator)
    else:
        _unitcell = unitcell

    # units keywords: factor, nac_factor, distance_to_A
    units = get_default_physical_units(calculator)
    phonon = Phonopy(_unitcell,
                     supercell_matrix,
                     primitive_matrix=primitive_matrix,
                     factor=units['factor'])

    if nac_params is None:
        if born_filename is None:
            _nac_params = None
        else:
            _nac_params = parse_BORN(phonon.primitive, filename=born_filename)
    else:
        _nac_params = nac_params

    if _nac_params is not None:
        if _nac_params['factor'] is None:
            _nac_params['factor'] = units['nac_factor']
        phonon.set_nac_params(_nac_params)

    if force_constants_filename is not None:
        dot_split = force_constants_filename.split('.')
        p2s_map = phonon.primitive.get_primitive_to_supercell_map()
        if len(dot_split) > 1 and dot_split[-1] == 'hdf5':
            fc = read_force_constants_hdf5(filename=force_constants_filename,
                                           p2s_map=p2s_map)
        else:
            fc = parse_FORCE_CONSTANTS(filename=force_constants_filename,
                                       p2s_map=p2s_map)
        phonon.set_force_constants(fc)
    elif force_sets_filename is not None:
        force_sets = parse_FORCE_SETS(filename=force_sets_filename)
        phonon.set_displacement_dataset(force_sets)
        phonon.produce_force_constants()

    return phonon
Exemplo n.º 11
0
def get_phonon(structure,
               NAC=False,
               setup_forces=True,
               super_cell_phonon=np.identity(3),
               primitive_matrix=np.identity(3),
               symmetrize=True):
    """
    Return a phonopy phonon object (instance of the class Phonon)
    
    :param structure: unit cell matrix (lattice vectors in rows)
    :param NAC: (Bool) activate/deactivate Non-analytic corrections
    :param setup_forces: (Bool) decide if pre-calculate harmonic forces in phonon object
    :param super_cell_phonon: 3x3 array containing the supercell to be used to calculate the force constants
    :param primitive_matrix: 3x3 array containing the primitive axis (in rows) which define the primitive cell
    :param symmetrize: decide if symmetrize the force constants
    :return: phonopy phonon object
    """

    phonon = Phonopy(structure,
                     super_cell_phonon,
                     primitive_matrix=primitive_matrix,
                     symprec=1e-5,
                     is_symmetry=symmetrize)

    # Non Analytical Corrections (NAC) from Phonopy [Frequencies only, eigenvectors no affected by this option]

    if setup_forces:
        if structure.get_force_constants() is not None:
            phonon.set_force_constants(
                structure.get_force_constants().get_array())
        elif structure.get_force_sets() is not None:
            phonon.set_displacement_dataset(
                structure.get_force_sets().get_dict())
            phonon.produce_force_constants(computation_algorithm="svd")
            structure.set_force_constants(
                ForceConstants(
                    phonon.get_force_constants(),
                    supercell=structure.get_force_sets().get_supercell()))
        else:
            print('No force sets/constants available!')
            exit()

    if NAC:
        print("Using non-analytical corrections")
        primitive = phonon.get_primitive()
        try:
            nac_params = parse_BORN(primitive, is_symmetry=True)
            phonon.set_nac_params(nac_params=nac_params)
        except OSError:
            print('Required BORN file not found!')
            exit()

    return phonon
Exemplo n.º 12
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()
     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
Exemplo n.º 13
0
def get_nac_params(primitive=None,
                   nac_params=None,
                   born_filename=None,
                   is_nac=True,
                   nac_factor=None,
                   log_level=0):
    if born_filename is not None:
        _nac_params = parse_BORN(primitive, filename=born_filename)
        if log_level:
            print("NAC params were read from \"%s\"." % born_filename)
    elif nac_params is not None:  # nac_params input or phonopy_yaml.nac_params
        _nac_params = nac_params
    elif is_nac and os.path.isfile("BORN"):
        _nac_params = parse_BORN(primitive, filename="BORN")
        if log_level:
            print("NAC params were read from \"BORN\".")
    else:
        _nac_params = None

    if _nac_params is not None and _nac_params['factor'] is None:
        _nac_params['factor'] = nac_factor

    return _nac_params
Exemplo n.º 14
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
Exemplo n.º 15
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]])
        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)
        nac_params['method'] = 'wang'
        phonon.set_nac_params(nac_params)

        return phonon
Exemplo n.º 16
0
def get_phonon(structure,
               NAC=False,
               setup_forces=True,
               custom_supercell=None,
               symprec=1e-5):

    if custom_supercell is None:
        super_cell_phonon = structure.get_supercell_phonon()
    else:
        super_cell_phonon = custom_supercell

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

    phonon = Phonopy(bulk,
                     super_cell_phonon,
                     primitive_matrix=structure.get_primitive_matrix(),
                     symprec=symprec)

    # Non Analytical Corrections (NAC) from Phonopy [Frequencies only, eigenvectors no affected by this option]

    if setup_forces:
        if structure.get_force_constants() is not None:
            phonon.set_force_constants(
                structure.get_force_constants().get_array())
        elif structure.get_force_sets() is not None:
            phonon.set_displacement_dataset(
                structure.get_force_sets().get_dict())
            phonon.produce_force_constants()
            structure.set_force_constants(
                ForceConstants(
                    phonon.get_force_constants(),
                    supercell=structure.get_force_sets().get_supercell()))
        else:
            print('No force sets/constants available!')
            exit()

    if NAC:
        print("Warning: Using Non Analytical Corrections")
        primitive = phonon.get_primitive()
        nac_params = parse_BORN(primitive, is_symmetry=True)
        phonon.set_nac_params(nac_params=nac_params)

    return phonon
Exemplo n.º 17
0
def get_initialized_phononopy_instance(initial_structure,
                                       phonopy_inputs,
                                       force_constants_path=None,
                                       born_path=None):
    """
	Initializes and returns a valid Phonopy instance and with displacements internally generated.

	If force_constants_path is specified, the phonopy instance is initialized with the force constants at the given path.
	If the born_path is specified, the born file at this path is used to initialize the nac parameters of the phonopy instance, but
	only if the nac key has a value of true in the phonopy_inputs dictionary.

	phonopy_inputs should be a dictionary that looks like:

	phonopy_inputs_dictionary = {
		'supercell_dimensions': [2, 2, 2],
		'symprec': 0.001,
		'displacement_distance': 0.01,
		'nac': True
		...
	}
	"""

    unit_cell_phonopy_structure = convert_structure_to_phonopy_atoms(
        initial_structure)
    supercell_dimensions_matrix = np.diag(
        phonopy_inputs['supercell_dimensions'])

    phonon = Phonopy(unitcell=unit_cell_phonopy_structure,
                     supercell_matrix=supercell_dimensions_matrix,
                     symprec=phonopy_inputs['symprec'])
    phonon.generate_displacements(
        distance=phonopy_inputs['displacement_distance'])

    if force_constants_path != None:
        force_constants = parse_FORCE_CONSTANTS(filename=force_constants_path)
        phonon.set_force_constants(force_constants)

    if born_path != None and (phonopy_inputs.has_key('nac')
                              and phonopy_inputs['nac']):
        nac_params = parse_BORN(phonon.get_primitive(), filename=born_path)
        phonon.set_nac_params(nac_params)

    return phonon
Exemplo n.º 18
0
def get_phonon(structure, NAC=False, setup_forces=True, custom_supercell=None):

    if custom_supercell is None:
        super_cell_phonon = structure.get_supercell_phonon()
    else:
        super_cell_phonon = custom_supercell

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

    phonon = Phonopy(bulk, super_cell_phonon,
                     primitive_matrix=structure.get_primitive_matrix(),
                     symprec=1e-5)

    # Non Analytical Corrections (NAC) from Phonopy [Frequencies only, eigenvectors no affected by this option]

    if setup_forces:
        if structure.get_force_constants() is not None:
            phonon.set_force_constants(structure.get_force_constants().get_array())
        elif structure.get_force_sets() is not None:
            phonon.set_displacement_dataset(structure.get_force_sets().get_dict())
            phonon.produce_force_constants()
            structure.set_force_constants(ForceConstants(phonon.get_force_constants(),
                                                         supercell=structure.get_force_sets().get_supercell()))
        else:
            print('No force sets/constants available!')
            exit()

    if NAC:
        print("Warning: Using Non Analytical Corrections")
        primitive = phonon.get_primitive()
        nac_params = parse_BORN(primitive, is_symmetry=True)
        phonon.set_nac_params(nac_params=nac_params)

    return phonon
Exemplo n.º 19
0
def obtain_phonon_dispersion_spectra(structure, bands_ranges, NAC=False, band_resolution=30):

    print("Calculating phonon dispersion spectra...")
    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,
    )

    if NAC:
        print("Phonopy warning: Using Non Analitical Corrections")
        print("BORN file is needed to do this")
        get_is_symmetry = True  # sfrom 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()

    bands = []
    for q_start, q_end in bands_ranges:
        band = []
        for i in range(band_resolution + 1):
            band.append(np.array(q_start) + (np.array(q_end) - np.array(q_start)) / band_resolution * i)
        bands.append(band)
    phonon.set_band_structure(bands)

    return phonon.get_band_structure()
Exemplo n.º 20
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:
# born = [[[1.08703, 0, 0],
#          [0, 1.08703, 0],
#          [0, 0, 1.08703]],
#         [[-1.08672, 0, 0],
#          [0, -1.08672, 0],
#          [0, 0, -1.08672]]]
# epsilon = [[2.43533967, 0, 0],
#            [0, 2.43533967, 0],
#            [0, 0, 2.43533967]]
# factors = 14.400
# nac_params = {'born': born,
#               'factor': factors,
#               'dielectric': epsilon}
phonon.set_nac_params(nac_params)
Exemplo n.º 21
0
def ir_intensity_phonopy(
    run_dir=".",
    vasprun="vasprun.xml",
    BornFileName="BORN",
    PoscarName="POSCAR",
    ForceConstantsName="FORCE_CONSTANTS",
    supercell=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
    nac=True,
    symprec=1e-5,
    primitive=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
    degeneracy_tolerance=1e-5,
    vector=[0, 0, 0],
    smoothen=False,
):
    """Calculate IR intensity using DFPT and phonopy."""
    from phonopy import Phonopy
    from phonopy.interface.vasp import read_vasp
    from phonopy.file_IO import (
        parse_BORN,
        parse_FORCE_CONSTANTS,
    )
    import shutil
    from phonopy.units import VaspToCm

    # from phonopy.phonon.degeneracy import (
    #    degenerate_sets as get_degenerate_sets,
    # )
    # adapted from https://github.com/JaGeo/IR
    # TODO: Make directory indepndent
    cwd = os.getcwd()
    print("Directory:", cwd)
    os.chdir(run_dir)
    if not os.path.exists(vasprun):
        shutil.copy2(vasprun, "vasprun.xml")
    cmd = str("phonopy --fc vasprun.xml")
    os.system(cmd)
    born_file = os.path.join(os.getcwd(), BornFileName)
    cmd = str("phonopy-vasp-born >  ") + str(born_file)
    os.system(cmd)
    from jarvis.io.vasp.outputs import Vasprun

    v = Vasprun(vasprun)
    strt = v.all_structures[0]
    strt.write_poscar(PoscarName)
    unitcell = read_vasp(PoscarName)
    phonon = Phonopy(
        unitcell,
        supercell_matrix=supercell,
        primitive_matrix=primitive,
        factor=VaspToCm,
        symprec=symprec,
    )
    natoms = phonon.get_primitive().get_number_of_atoms()
    force_constants = parse_FORCE_CONSTANTS(filename=ForceConstantsName)
    phonon.set_force_constants(force_constants)
    masses = phonon.get_primitive().get_masses()
    phonon.set_masses(masses)
    BORN_file = parse_BORN(phonon.get_primitive(), filename=BornFileName)
    BORN_CHARGES = BORN_file["born"]
    # print ('born_charges2',BORN_CHARGES)
    if nac:
        phonon.set_nac_params(BORN_file)
    frequencies, eigvecs = phonon.get_frequencies_with_eigenvectors(vector)
    # frequencies=VaspToTHz*frequencies/VaspToCm
    # x, y = ir_intensity(
    #    phonon_eigenvectors=np.real(eigvecs),
    #    phonon_eigenvalues=frequencies,
    #    masses=masses, #np.ones(len(masses)),
    #    born_charges=born_charges,
    #    smoothen=smoothen,
    # )
    NumberOfBands = len(frequencies)
    EigFormat = {}
    for alpha in range(NumberOfBands):
        laufer = 0
        for beta in range(natoms):
            for xyz in range(0, 3):
                EigFormat[beta, alpha, xyz] = eigvecs[laufer][alpha]
                laufer = laufer + 1
    Intensity = {}
    intensities = []
    for freq in range(len(frequencies)):
        Intensity[freq] = 0
        tmp = 0
        for alpha in range(3):
            asum = 0
            for n in range(natoms):
                for beta in range(3):
                    asum = asum + BORN_CHARGES[n, alpha, beta] * np.real(
                        EigFormat[n, freq, beta]
                    ) / np.sqrt(masses[n])
                    tmp += asum
            Intensity[freq] = Intensity[freq] + np.power(np.absolute(asum), 2)
        intensities.append(Intensity[freq])
    os.chdir(cwd)
    return frequencies, intensities
Exemplo n.º 22
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:
# born = [[[1.08703, 0, 0],
#          [0, 1.08703, 0],
#          [0, 0, 1.08703]],
#         [[-1.08672, 0, 0],
#          [0, -1.08672, 0],
#          [0, 0, -1.08672]]]
# epsilon = [[2.43533967, 0, 0],
#            [0, 2.43533967, 0],
#            [0, 0, 2.43533967]]
# factors = 14.400
# nac_params = {'born': born,
#               'factor': factors,
#               'dielectric': epsilon}
phonon.set_nac_params(nac_params)
Exemplo n.º 23
0
# 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])
q_end = np.array([0, 0, 0])
band = []
for i in range(51):
    band.append(q_start + (q_end - q_start) / 50 * i)
bands.append(band)
Exemplo n.º 24
0
    def __init__(self, PoscarName='POSCAR', BornFileName='BORN', ForceConstants=False, ForceFileName='FORCE_SETS',
                 supercell=[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
                 , nac=False, symprec=1e-5, masses=[], primitive=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                 degeneracy_tolerance=1e-5):
        """
        Class for calculating the IR spectra in the dipole approximation according to:
        P. Giannozzi and S. Baroni, J. Chem. Phys. 100, 8537 (1994).
        and
        D. Karhanek, T. Bucko, J. Hafner, J. Phys.: Condens. Matter 22 265006 (2010).


        This class was also carefully compared to the results of the script by D. Karhanek available at http://homepage.univie.ac.at/david.karhanek/downloads.html

        args:
            PoscarNamse (str): name of the POSCAR that was used for the phonon calculation
            BornFileName (str): name of the file with BORN charges (formatted with outcar-born)
            ForceConstants (boolean): If True, ForceConstants are read in. If False, forces are read in.
            ForceFileName (str): name of the file including force constants or forces
            supercell (list of lists): reads in supercell
            nac (boolean): If true, NAC is applied.
            symprec (float): contains symprec tag as used in Phonopy
            masses (list): Masses in this list are used instead of the ones prepared in Phonopy. Useful for isotopes.
            primitive (list of lists): contains rotational matrix to arrive at primitive cell
            degeneracy_tolerance (float): tolerance for degenerate modes
        """

        self.__unitcell = read_vasp(PoscarName)
        self.__supercell = supercell
        self.__phonon = Phonopy(self.__unitcell, supercell_matrix=self.__supercell, primitive_matrix=primitive,
                                factor=VaspToCm, symprec=symprec)
        self.__natoms = self.__phonon.get_primitive().get_number_of_atoms()
        self._degeneracy_tolerance = degeneracy_tolerance
        # If different masses are supplied
        if not ForceConstants:
            self.__force_sets = parse_FORCE_SETS(filename=ForceFileName)
            self.__phonon.set_displacement_dataset(self.__force_sets)
            self.__phonon.produce_force_constants()

        if ForceConstants:
            force_constants = parse_FORCE_CONSTANTS(filename=ForceFileName)
            self.__phonon.set_force_constants(force_constants)


        if masses:
            self.__phonon._build_supercell()
            self.__phonon._build_primitive_cell()
            # if ForceConstants:
            #     force_constants = parse_FORCE_CONSTANTS(filename=ForceFileName)
            #     self.__phonon.set_force_constants(force_constants)
            self.__phonon.set_masses(masses)

        self.__masses = self.__phonon.get_primitive().get_masses()
        # Forces or Force Constants

        # Read in BORN file
        BORN_file = parse_BORN(self.__phonon.get_primitive(), filename=BornFileName)
       
        self.__BORN_CHARGES = BORN_file['born']

        # Apply NAC Correction
        if nac:
            self.__phonon.set_nac_params(BORN_file)
        self._frequencies, self._eigvecs = self.__phonon.get_frequencies_with_eigenvectors([0, 0, 0])

        self.__NumberOfBands = len(self._frequencies)

        # Nicer format of the eigenvector file
        self.__FormatEigenvectors()

        # Get dipole approximation of the intensitiess
        self.__set_intensities()
Exemplo n.º 25
0
def load_phonopy(filename, structure, dim, symprec=0.01, primitive_matrix=None,
                 factor=VaspToTHz, symmetrise=True, born=None, write_fc=False):
    """Load phonopy output and return an ``phonopy.Phonopy`` object.

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

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

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

        elif 'FORCE_CONSTANTS' == filename:
            fc = file_IO.parse_FORCE_CONSTANTS(filename=filename)

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

        phonon.set_force_constants(fc)

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

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

        phonon.set_displacement_dataset(fs)

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

    if born:
        # load born parameters from a file
        nac_params = file_IO.parse_BORN(phonon._primitive,
                                        symprec=symprec,
                                        filename=born)

        # set the nac unit conversion factor manual,  specific to VASP
        nac_params['factor'] = Hartree * Bohr
        phonon.set_nac_params(nac_params)

    if symmetrise:
        phonon.symmetrize_force_constants()

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

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

    return phonon
    def __init__(self,
                 PoscarName='POSCAR',
                 ForceConstants=False,
                 ForceFileName='FORCE_SETS',
                 BornFileName='BORN',
                 supercell=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                 nac=False,
                 symprec=1e-5,
                 masses=[],
                 primitive=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                 degeneracy_tolerance=1e-4,
                 factor=VaspToCm,
                 q=[0, 0, 0]):
        """Class that calculates contributions of each atom to the phonon modes at Gamma
            Args:
            PoscarName (str): name of the POSCAR that was used for the phonon calculation
            BornFileName (str): name of the file with BORN charges (formatted with outcar-born)
            ForceConstants (boolean): If True, ForceConstants are read in. If False, forces are read in.
            ForceFileName (str): name of the file including force constants or forces
            supercell (list of lists): reads in supercell
            nac (boolean): If true, NAC is applied. (please be careful if you give a primitive cell. NAC should then be calculated for primitive cell)
            symprec (float): contains symprec tag as used in Phonopy
            masses (list): Masses in this list are used instead of the ones prepared in Phonopy. Useful for isotopes.
            primitive (list of lists): contains rotational matrix to arrive at primitive cell
            factor (float): VaspToCm or VaspToTHz or VaspToEv
            q (list of int): q point for the plot. So far only Gamma works

        """

        self.__unitcell = read_vasp(PoscarName)
        self.__supercell = supercell
        self.__phonon = Phonopy(self.__unitcell,
                                supercell_matrix=self.__supercell,
                                primitive_matrix=primitive,
                                factor=factor,
                                symprec=symprec)
        self.__natoms = self.__phonon.get_primitive().get_number_of_atoms()
        self.__symbols = self.__phonon.get_primitive().get_chemical_symbols()
        self.__factor = factor
        # If different masses are supplied
        if masses:
            self.__phonon.set_masses(masses)
        self.__masses = self.__phonon.get_primitive().get_masses()

        # Forces or Force Constants
        if not ForceConstants:
            self.__set_ForcesSets(filename=ForceFileName, phonon=self.__phonon)

        if ForceConstants:
            self.__set_ForceConstants(filename=ForceFileName,
                                      phonon=self.__phonon)

        # Apply NAC Correction
        if nac:
            BORN_file = parse_BORN(self.__phonon.get_primitive(),
                                   filename=BornFileName)
            self.__BORN_CHARGES = BORN_file['born']
            self.__phonon.set_nac_params(BORN_file)

        # frequencies and eigenvectors at Gamma
        self._frequencies, self._eigvecs = self.__phonon.get_frequencies_with_eigenvectors(
            q)

        self.__NumberOfBands = len(self._frequencies)

        # Nicer format of the eigenvector file
        self.__FormatEigenvectors()

        # Get Contributions
        self.__set_Contributions()
        self.__set_Contributions_withoutmassweight()

        # irrepsobject
        try:
            self.__set_IRLabels(phonon=self.__phonon,
                                degeneracy_tolerance=degeneracy_tolerance,
                                factor=factor,
                                q=q,
                                symprec=symprec)
        except:
            print(
                "Cannot assign IR labels. Play around with symprec, degeneracy_tolerance. The point group could not be implemented."
            )
            self.__freqlist = {}
            for i in range(0, len(self._frequencies)):
                self.__freqlist[i] = i
Exemplo n.º 27
0
import numpy as np
from phonopy import Phonopy
from phonopy.structure.symmetry import Symmetry
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_FORCE_SETS, parse_BORN
from phonopy.structure.spglib import get_stabilized_reciprocal_mesh
from phonopy.structure.tetrahedron_method import TetrahedronMethod
from phonopy.phonon.tetrahedron_mesh import TetrahedronMesh

cell = read_vasp(sys.argv[1])
phonon = Phonopy(cell, [[2, 0, 0], [0, 2, 0], [0, 0, 2]], is_auto_displacements=False)
force_sets = parse_FORCE_SETS()
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]])
primitive = phonon.get_primitive()
born = parse_BORN(primitive)
phonon.set_nac_params(born)
symmetry = phonon.get_primitive_symmetry()
mesh = [20, 20, 20]
# phonon.set_mesh(mesh)
# phonon.set_total_DOS(sigma=0.1)
# phonon.plot_total_DOS().show()

rotations = symmetry.get_pointgroup_operations()
thm = TetrahedronMesh(phonon.get_dynamical_matrix(),
                      mesh,
                      rotations,
                      is_gamma_center=True)
                      
thm.run_dos()
for f, iw in zip(thm.get_frequency_points(), thm.get_integration_weights()):
Exemplo n.º 28
0
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])
print dmat

# Example of band structure calculation
bands = []
q_start = np.array([1./3, 1./3, 0])
q_end = np.array([0, 0, 0])
band = []
for i in range(51):
    band.append(q_start + (q_end - q_start) / 50 * i)
bands.append(band)
Exemplo n.º 29
0
def phonopy_to_abinit(unit_cell,
                      supercell_matrix,
                      out_ddb_path,
                      ngqpt=None,
                      qpt_list=None,
                      force_constants=None,
                      force_sets=None,
                      born=None,
                      primitive_matrix="auto",
                      symprec=1e-5,
                      tolsym=None,
                      supercell=None,
                      calculator=None,
                      manager=None,
                      workdir=None,
                      pseudos=None,
                      verbose=False):
    """
    Converts the data from phonopy to an abinit DDB file. The data can be provided
    in form of arrays or paths to the phonopy files that should be parsed.
    The minimal input should contains the FORCE_CONSTANTS or FORCE_SETS.
    If BORN is present the Born effective charges (BEC) and dielectric
    tensor will also be added to the DDB.

    The best agreement is obtained with supercell_matrix and ngqpt being
    equivalent (i.e. supercell_matrix a diagonal matrix with ngqpt as diagonal
    elements). Non diagonal supercell_matrix are allowed as well, but the information
    encoded in the DDB will be the result of an interpolation done through phonopy.

    Phonopy is used to convert the IFC to the dynamical matrix. However, in order to
    determine the list of q-points in the irreducible Brillouin zone and to prepare the
    base for the final DDB file, abinit will be called for a very short and inexpensive run.

    Performs a check to verify if the two codes identify the same symmetries and it gives a
    warning in case of failure. Mismatching symmetries may lead to incorrect conversions.

    Args:
        unit_cell: a |Structure| object that identifies the unit cell used for the phonopy
            calculation.
        supercell_matrix: a 3x3 array representing the supercell matrix used to generated the
            forces with phonopy.
        out_ddb_path: a full path to the file where the new DDB will be written
        ngqpt: a list of 3 elements indicating the grid of q points that will be used in the DDB.
        qpt_list: alternatively to ngqpt an explicit list of q-points can be provided here.
            At least one among ngqpt and qpt_list should be defined.
        force_constants: an array with shape (num atoms unit cell, num atoms supercell, 3, 3)
            containing the force constants. Alternatively a string with the path to the
            FORCE_CONSTANTS file. This or force_set should be defined. If both given this
            has precedence.
        force_sets: a dictionary obtained from the force sets generated with phonopy.
            Alternatively a string with the path to the FORCE_SETS file. This or force_constants
            should be defined.
        born: a dictionary with "dielectric" and "born" keywords as obtained from the nac_params
            in phonopy. Alternatively a string with the path to the BORN file. Notice that
            the "factor" attribute is not taken into account, so the values should be in
            default phonopy units.
        primitive_matrix: a 3x3 array with the primitive matrix passed to Phonopy. "auto" will
            use spglib to try to determine it automatically. If the DDB file should contain the
            actual unit cell this should be the identity matrix.
        symprec: distance tolerance in Cartesian coordinates to find crystal symmetry in phonopy.
            It might be that the value should be tuned so that it leads to the the same symmetries
            as in the abinit calculation.
        tolsym: Gives the tolerance to identify symmetries in abinit. See abinit documentation for
            more details.
        supercell: if given it should represent the supercell used to get the force constants,
            without any perturbation. It will be used to match it to the phonopy supercell
            and sort the IFC in the correct order.
        calculator: a string with the name of the calculator. Will be used to set the conversion
            factor for the force constants coming from phonopy.
        manager: |TaskManager| object. If None, the object is initialized from the configuration file
        pseudos: List of filenames or list of |Pseudo| objects or |PseudoTable| object. It will be
            used by abinit to generate the base DDB file. If None the abipy.data.hgh_pseudos.HGH_TABLE
            table will be used.
        verbose: verbosity level. Set it to a value > 0 to get more information
        workdir: path to the directory where the abinit calculation will be executed.

    Returns:
        a DdbFile instance of the file written in out_ddb_path.
    """

    if ngqpt is None and qpt_list is None:
        raise ValueError(
            "at least one among nqgpt and qpt_list should be defined")

    if force_sets is None and force_constants is None:
        raise ValueError(
            "at least one of force_sets and force_constants should be provided"
        )

    phon_at = get_phonopy_structure(unit_cell)

    if isinstance(force_constants, str):
        force_constants = parse_FORCE_CONSTANTS(filename=force_constants)
    elif force_constants is not None:
        force_constants = np.array(force_constants)
        force_sets = None

    if isinstance(force_sets, str):
        force_sets = parse_FORCE_SETS(filename=force_sets)

    # no nac_params here, otherwise they will be used for the interpolation
    phonon = Phonopy(phon_at,
                     supercell_matrix,
                     primitive_matrix=primitive_matrix,
                     nac_params=None,
                     symprec=symprec,
                     calculator=calculator)

    primitive = get_pmg_structure(phonon.primitive)

    if isinstance(born, str):
        born = parse_BORN(phonon.primitive, filename=born)

    if supercell is not None:
        ph_supercell = get_pmg_structure(phonon.supercell)
        if not np.allclose(supercell.lattice.matrix,
                           ph_supercell.lattice.matrix):
            raise RuntimeError("The lattice of the supercells do not match")
        sc_mapping = []
        for i, site_orig in enumerate(supercell):
            for j, site_ph in enumerate(ph_supercell):
                d = supercell.lattice.get_distance_and_image(
                    site_orig.frac_coords, site_ph.frac_coords)[0]
                if d < 1e-5:
                    sc_mapping.append(j)
                    break
            else:
                raise RuntimeError(
                    f"Could not find a match for site {i} with coords "
                    f"{site_orig.cart_coords} in the supercell.")

        # cross check that the same atom was not matched twice
        n_matches = len(set(sc_mapping))
        if n_matches < len(supercell):
            raise RuntimeError(
                f"Found matches for {n_matches} different atoms in the supercell: {sc_mapping}"
            )

        force_constants = force_constants[:, sc_mapping]

    if force_constants is not None:
        phonon.set_force_constants(force_constants)
    else:
        phonon.dataset = force_sets
        phonon.produce_force_constants()

    if calculator:
        units = get_default_physical_units(calculator)
        fc_factor = get_force_constant_conversion_factor(
            units["force_constants_unit"], None)
        phonon.set_force_constants(phonon.force_constants * fc_factor)

    if pseudos is None:
        from abipy.data.hgh_pseudos import HGH_TABLE
        pseudos = HGH_TABLE

    inp = minimal_scf_input(primitive, pseudos)

    # get the qpoints list if not defined
    if qpt_list is None:
        inp["ngkpt"] = ngqpt
        qpt_list = inp.abiget_ibz(verbose=verbose)[0]

    dm_list = get_dm(phonon, qpt_list, primitive)

    if born is not None:
        # for the conversion of the BEC the zion (i.e. the ionic charge of the pseudo)
        # it is an additive factor and should be the same that goes in the header of the DDB,
        # so take it from the pseudos used to generate it.
        zion = inp.valence_electrons_per_atom
        born_data = generate_born_deriv(born, zion, primitive)
    else:
        born_data = None

    inp = minimal_scf_input(primitive, pseudos)
    if tolsym is not None:
        inp["tolsym"] = tolsym
    task = inp.run_in_shell(workdir=workdir, manager=manager, verbose=verbose)

    # use the output of abinit to check that the spacegroup identified by
    # phonopy and abinit are the same.
    with GsrFile(task.opath_from_ext("GSR.nc")) as gsr:
        abi_spg = gsr.structure.abi_spacegroup.spgid
    spglib_spg = phonon.symmetry.dataset["number"]
    if abi_spg != spglib_spg:
        warnings.warn(
            "The space group number obtained based on the DDB symmetries differs "
            f"from the one calculated with spglib: {abi_spg} versus "
            f"{spglib_spg}. The convertion may be incorrect. Try changing symprec or tolsym."
        )

    tmp_ddb_path = task.opath_from_ext("DDB")

    ddb = DdbFile(tmp_ddb_path)
    # remove the blocks generated by the calculation and that are meaningless
    ddb.remove_block(dord=0)
    ddb.remove_block(dord=1)

    add_data_ddb(ddb, dm_list, qpt_list, born_data)

    ddb.write(out_ddb_path)

    new_ddb = DdbFile(out_ddb_path)
    return new_ddb