Beispiel #1
0
    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)
Beispiel #2
0
    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