def from_ddb(cls, ddb_path, directions=None, labels=None, num_points=20, qpt_norm=0.1, ignore_neg_freqs=True, asr=2, chneut=1, dipdip=1, ngqpt=None, spell_check=True, anaddb_kwargs=None, verbose=0, mpi_procs=1, workdir=None, manager=None): """ Creates and instance of the object. Runs anaddb along the specified directions or the standard directions in the standard paths given in :cite:`Setyawan2010`. The values of the speed of sound will be calculated as the slope of the linear fits along each direction. Args: ddb_path (str): path to the ddb file. directions (list): list of qpoints identifying the directions for the calculation of the speed of sound. In fractional coordinates. labels (list): list of string with the name of the directions. num_points (int): number of points calculated along each direction and used to fit the speed of sound. qpt_norm (float): Norm of the largest point in fractional coordinates for each of the directions considered. ignore_neg_freqs (bool): if True points with negative frequencies will not be considered in the fit, in order to ignore inaccuracies in the long range behavior. asr, chneut, dipdip: Anaddb input variable. See official documentation. ngqpt: Number of divisions for the q-mesh in the DDB file. Auto-detected if None (default). anaddb_kwargs: additional kwargs for anaddb. verbose: verbosity level. Set it to a value > 0 to get more information. mpi_procs: Number of MPI processes to use. workdir: Working directory. If None, a temporary directory is created. manager: |TaskManager| object. If None, the object is initialized from the configuration file. long. Returns: an instance of SoundVelocity """ with DdbFile(ddb_path) as ddb: if ngqpt is None: ngqpt = ddb.guessed_ngqpt inp = AnaddbInput(ddb.structure, comment="ANADDB input for speed of sound", anaddb_kwargs=anaddb_kwargs, spell_check=spell_check) q1shft = [[0, 0, 0]] inp.set_vars( ifcflag=1, ngqpt=np.array(ngqpt), q1shft=q1shft, nqshft=len(q1shft), asr=asr, chneut=chneut, dipdip=dipdip, ) if not directions: hs = ddb.structure.hsym_kpath kpath = hs.kpath directions = [] labels = [] for chunk in kpath["path"]: for i, q in enumerate(chunk): if "Gamma" in q: if i > 0 and q not in labels: new_q = kpath["kpoints"][chunk[i - 1]] directions.append(new_q) labels.append(chunk[i - 1]) if i < len(chunk) - 1 and q not in labels: new_q = kpath["kpoints"][chunk[i + 1]] directions.append(new_q) labels.append(chunk[i + 1]) qpts = [] for q in directions: q = qpt_norm * q / np.linalg.norm(q) steps = q / num_points qpts.extend((steps[:, None] * np.arange(num_points)).T) n_qpoints = len(qpts) qph1l = np.zeros((n_qpoints, 4)) qph1l[:, :-1] = qpts qph1l[:, -1] = 1 inp['qph1l'] = qph1l.tolist() inp['nph1l'] = n_qpoints task = ddb._run_anaddb_task(inp, mpi_procs=mpi_procs, workdir=workdir, manager=manager, verbose=verbose) phbst_path = os.path.join(task.workdir, "run.abo_PHBST.nc") return cls.from_phbst(phbst_path, ignore_neg_freqs=ignore_neg_freqs, labels=labels)
def get_anaddb_input(self, item): """ creates the AnaddbInput object. It also returns the list of qpoints labels for generating the PhononBandStructureSymmLine. """ ngqpt = item["abinit_input.ngqpt"] q1shft = [(0, 0, 0)] structure = Structure.from_dict(item["abinit_input.structure"]) hs = HighSymmKpath(structure, symprec=1e-2) spgn = hs._sym.get_space_group_number() if spgn != item["spacegroup.number"]: raise RuntimeError("Parsed specegroup number {} does not match " "calculation spacegroup {}".format(spgn, item["spacegroup.number"])) # for the moment use gaussian smearing prtdos = 1 dossmear = 3 / Ha_cmm1 lo_to_splitting = True dipdip = 1 asr = 2 chneut = 1 ng2qppa = 50000 inp = AnaddbInput(structure, comment="ANADB input for phonon bands and DOS") inp.set_vars( ifcflag=1, ngqpt=np.array(ngqpt), q1shft=q1shft, nqshft=len(q1shft), asr=asr, chneut=chneut, dipdip=dipdip, ) # Parameters for the dos. ng2qpt = KSampling.automatic_density(structure, kppa=ng2qppa).kpts[0] inp.set_vars(prtdos=prtdos, dosdeltae=None, dossmear=dossmear, ng2qpt=ng2qpt) # Parameters for the BS qpts, labels_list = hs.get_kpoints(line_density=18, coords_are_cartesian=False) n_qpoints = len(qpts) qph1l = np.zeros((n_qpoints, 4)) qph1l[:, :-1] = qpts qph1l[:, -1] = 1 inp['qph1l'] = qph1l.tolist() inp['nph1l'] = n_qpoints if lo_to_splitting: kpath = hs.kpath directions = [] for qptbounds in kpath['path']: for i, qpt in enumerate(qptbounds): if np.array_equal(kpath['kpoints'][qpt], (0, 0, 0)): # anaddb expects cartesian coordinates for the qph2l list if i > 0: directions.extend(structure.lattice.reciprocal_lattice_crystallographic.get_cartesian_coords( kpath['kpoints'][qptbounds[i - 1]])) directions.append(0) if i < len(qptbounds) - 1: directions.extend(structure.lattice.reciprocal_lattice_crystallographic.get_cartesian_coords( kpath['kpoints'][qptbounds[i + 1]])) directions.append(0) if directions: directions = np.reshape(directions, (-1, 4)) inp.set_vars( nph2l=len(directions), qph2l=directions ) return inp, labels_list