Ejemplo n.º 1
0
    def anaget_emacro_and_becs(self, chneut=1, workdir=None, manager=None, verbose=0):
        """
        Call anaddb to compute the macroscopic dielectric tensor and the Born effective charges.

        Args:
            chneut: Anaddb input variable. See official documentation.
            manager: :class:`TaskManager` object. If None, the object is initialized from the configuration file
            verbose: verbosity level. Set it to a value > 0 to get more information

        Return:
            emacro, becs 
        """
        inp = AnaddbInput(self.structure, anaddb_kwargs={"chneut": chneut})

        task = AnaddbTask.temp_shell_task(inp, ddb_node=self.filepath, workdir=workdir, manager=manager)

        if verbose: 
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise self.AnaddbError(task=task, report=report)

        # Read data from the netcdf output file produced by anaddb.
        with ETSF_Reader(os.path.join(task.workdir, "anaddb.nc")) as r:
            structure = r.read_structure()

            emacro = Tensor.from_cartesian_tensor(r.read_value("emacro_cart"), structure.lattice, space="r"),
            becs = Becs(r.read_value("becs_cart"), structure, chneut=inp["chneut"], order="f")

            return emacro, becs
Ejemplo n.º 2
0
 def test_AnaDdbAbinitTask(self):
     ana_inp = AnaddbInput.phbands_and_dos(self.si_structure,
                                           ngqpt=[4, 4, 4],
                                           nqsmall=10)
     task = abinit_tasks.AnaDdbAbinitTask(ana_inp)
     task.to_dict()
     self.assertFwSerializable(task)
Ejemplo n.º 3
0
def abinp_anaph(options):
    """Build Anaddb input file for the computation of phonon bands DOS."""
    ddb = DdbFile(options.filepath)
    nqsmall = 10
    inp = AnaddbInput.phbands_and_dos(ddb.structure, ddb.guessed_ngqpt, nqsmall, ndivsm=20, q1shft=(0, 0, 0),
        qptbounds=None, asr=2, chneut=0, dipdip=1, dos_method="tetra", lo_to_splitting=False,
        anaddb_args=None, anaddb_kwargs=None)

    return finalize(inp, options)
Ejemplo n.º 4
0
def abinp_anaph(options):
    """Build Anaddb input file for the computation of phonon bands DOS."""
    ddb = DdbFile(options.filepath)
    nqsmall = 10
    inp = AnaddbInput.phbands_and_dos(ddb.structure, ddb.guessed_ngqpt, nqsmall, ndivsm=20, q1shft=(0, 0, 0),
        qptbounds=None, asr=2, chneut=0, dipdip=1, dos_method="tetra", lo_to_splitting=False,
        anaddb_args=None, anaddb_kwargs=None)

    return finalize(inp, options)
Ejemplo n.º 5
0
    def anaget_ifc(self,
                   ifcout=None,
                   asr=2,
                   chneut=1,
                   dipdip=1,
                   ngqpt=None,
                   workdir=None,
                   manager=None,
                   verbose=0,
                   anaddb_kwargs=None):
        """
        Execute anaddb to compute the interatomic forces.

        Args:
            ifcout: Number of neighbouring atoms for which the ifc's will be output. If None all the atoms in the big box.
            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)
            workdir: Working directory. If None, a temporary directory is created.
            manager: :class:`TaskManager` object. If None, the object is initialized from the configuration file
            verbose: verbosity level. Set it to a value > 0 to get more information
            anaddb_kwargs: additional kwargs for anaddb

        Returns:
            :class:`InteratomicForceConstants` with the calculated ifc.
        """
        if ngqpt is None: ngqpt = self.guessed_ngqpt

        inp = AnaddbInput.ifc(self.structure,
                              ngqpt=ngqpt,
                              ifcout=ifcout,
                              q1shft=(0, 0, 0),
                              asr=asr,
                              chneut=chneut,
                              dipdip=dipdip,
                              anaddb_kwargs=anaddb_kwargs)

        task = AnaddbTask.temp_shell_task(inp,
                                          ddb_node=self.filepath,
                                          workdir=workdir,
                                          manager=manager)

        if verbose:
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise self.AnaddbError(task=task, report=report)

        return InteratomicForceConstants.from_file(
            os.path.join(task.workdir, 'anaddb.nc'))
Ejemplo n.º 6
0
    def anaget_phbst_and_phdos_files(self, nqsmall=10, ndivsm=20, asr=2, chneut=1, dipdip=1, dos_method="tetra",
                                       ngqpt=None, workdir=None, manager=None, verbose=0, lo_to_splitting=False):
        """
        Execute anaddb to compute the phonon band structure and the phonon DOS

        Args:
            nqsmall: Defines the homogeneous q-mesh used for the DOS. Gives the number of divisions 
                used to sample the smallest lattice vector.
            ndivsm: Number of division used for the smallest segment of the q-path
            asr, chneut, dipdp: Anaddb input variable. See official documentation.
            dos_method: Technique for DOS computation in  Possible choices: "tetra", "gaussian" or "gaussian:0.001 eV".
                In the later case, the value 0.001 eV is used as gaussian broadening
            ngqpt: Number of divisions for the q-mesh in the DDB file. Auto-detected if None (default)
            workdir: Working directory. If None, a temporary directory is created.
            manager: :class:`TaskManager` object. If None, the object is initialized from the configuration file
            verbose: verbosity level. Set it to a value > 0 to get more information
            lo_to_splitting: if True calculation of the LO-TO splitting will be calculated and included in the
                band structure

        Returns:
            :class:`PhbstFile` with the phonon band structure.
            :class:`PhdosFile` with the the phonon DOS.
        """
        if ngqpt is None: ngqpt = self.guessed_ngqpt

        inp = AnaddbInput.phbands_and_dos(
            self.structure, ngqpt=ngqpt, ndivsm=ndivsm, nqsmall=nqsmall, q1shft=(0,0,0), qptbounds=None,
            asr=asr, chneut=chneut, dipdip=dipdip, dos_method=dos_method, lo_to_splitting=lo_to_splitting)

        task = AnaddbTask.temp_shell_task(inp, ddb_node=self.filepath, workdir=workdir, manager=manager)

        if verbose: 
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise self.AnaddbError(task=task, report=report)

        phbst = task.open_phbst()

        if lo_to_splitting:
            with ETSF_Reader(os.path.join(task.workdir, "anaddb.nc")) as r:
                directions = r.read_value("non_analytical_directions")
                non_anal_phfreq = r.read_value("non_analytical_phonon_modes")

                phbst.phbands.non_anal_directions = directions
                phbst.phbands.non_anal_phfreqs = non_anal_phfreq

        return phbst, task.open_phdos()
Ejemplo n.º 7
0
    def anaget_phmodes_at_qpoint(self, qpoint=None, asr=2, chneut=1, dipdip=1, 
                                 workdir=None, manager=None, verbose=0):
        """
        Execute anaddb to compute phonon modes at the given q-point.

        Args:
            qpoint: Reduced coordinates of the qpoint where phonon modes are computed.
            asr, chneut, dipdp: Anaddb input variable. See official documentation.
            workdir: Working directory. If None, a temporary directory is created.
            manager: :class:`TaskManager` object. If None, the object is initialized from the configuration file
            verbose: verbosity level. Set it to a value > 0 to get more information

        Return:
            :class:`PhononBands` object.
        """
        if qpoint is None:
            qpoint = self.qpoints[0] 
            if len(self.qpoints) != 1:
                raise ValueError("%s contains %s qpoints and the choice is ambiguous.\n" 
                                 "Please specify the qpoint." % (self, len(self.qpoints)))

        # Check if qpoint is in the DDB.
        try:
            self.qindex(qpoint)
        except:
            raise ValueError("input qpoint %s not in ddb.qpoints:%s\n" % (qpoint, self.qpoints))

        inp = AnaddbInput.modes_at_qpoint(self.structure, qpoint, asr=asr, chneut=chneut, dipdip=dipdip)

        task = AnaddbTask.temp_shell_task(inp, ddb_node=self.filepath, workdir=workdir, manager=manager)

        if verbose: 
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here
        task.start_and_wait(autoparal=False)
        report = task.get_event_report()
        if not report.run_completed:
            raise self.AnaddbError(task=task, report=report)

        with task.open_phbst() as ncfile:
            return ncfile.phbands
Ejemplo n.º 8
0
    def anaget_phbst_and_phdos_files(self, nqsmall=10, ndivsm=20, asr=2, chneut=1, dipdip=1, 
                                       dos_method="tetra", ngqpt=None, workdir=None, manager=None, verbose=0):
        """
        Execute anaddb to compute the phonon band structure and the phonon DOS

        Args:
            nqsmall: Defines the homogeneous q-mesh used for the DOS. Gives the number of divisions 
                used to sample the smallest lattice vector.
            ndivsm: Number of division used for the smallest segment of the q-path
            asr, chneut, dipdp: Anaddb input variable. See official documentation.
            dos_method: Technique for DOS computation in  Possible choices: "tetra", "gaussian" or "gaussian:0.001 eV".
                In the later case, the value 0.001 eV is used as gaussian broadening
            ngqpt: Number of divisions for the q-mesh in the DDB file. Auto-detected if None (default)
            workdir: Working directory. If None, a temporary directory is created.
            manager: :class:`TaskManager` object. If None, the object is initialized from the configuration file
            verbose: verbosity level. Set it to a value > 0 to get more information

        Returns:
            :class:`PhbstFile` with the phonon band structure.
            :class:`PhdosFile` with the the phonon DOS.
        """
        if ngqpt is None: ngqpt = self.guessed_ngqpt

        inp = AnaddbInput.phbands_and_dos(
            self.structure, ngqpt=ngqpt, ndivsm=ndivsm, nqsmall=nqsmall, 
            q1shft=(0,0,0), qptbounds=None, asr=asr, chneut=chneut, dipdip=dipdip, dos_method=dos_method)

        task = AnaddbTask.temp_shell_task(inp, ddb_node=self.filepath, workdir=workdir, manager=manager)

        if verbose: 
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise self.AnaddbError(task=task, report=report)

        return task.open_phbst(), task.open_phdos()
Ejemplo n.º 9
0
    def from_ddb_list(cls, ddb_list, nqsmall=10, qppa=None, ndivsm=20, line_density=None, asr=2, chneut=1, dipdip=1,
                     dos_method="tetra", lo_to_splitting="automatic", ngqpt=None, qptbounds=None, anaddb_kwargs=None,
                     verbose=0, mpi_procs=1, workdir=None, manager=None):
        """
        Execute anaddb to compute generate the object from a list of ddbs.

        Args:
            ddb_list: A list with the paths to the ddb_files at different volumes. There should be an odd number of
                DDB files and the volume increment must be constant. The DDB files will be ordered according to the
                volume of the unit cell and the middle one will be considered as the DDB at the relaxed volume.
            nqsmall: Defines the homogeneous q-mesh used for the DOS. Gives the number of divisions
                used to sample the smallest lattice vector. If 0, DOS is not computed and
                (phbst, None) is returned.
            qppa: Defines the homogeneous q-mesh used for the DOS in units of q-points per reciprocal atom.
                Overrides nqsmall.
            ndivsm: Number of division used for the smallest segment of the q-path.
            line_density: Defines the a density of k-points per reciprocal atom to plot the phonon dispersion.
                Overrides ndivsm.
            asr, chneut, dipdip: Anaddb input variable. See official documentation.
            dos_method: Technique for DOS computation in  Possible choices: "tetra", "gaussian" or "gaussian:0.001 eV".
                In the later case, the value 0.001 eV is used as gaussian broadening.
            lo_to_splitting: Allowed values are [True, False, "automatic"]. Defaults to "automatic"
                If True the LO-TO splitting will be calculated and the non_anal_directions
                and the non_anal_phfreqs attributes will be addeded to the phonon band structure.
                "automatic" activates LO-TO if the DDB file contains the dielectric tensor and Born effective charges.
            ngqpt: Number of divisions for the q-mesh in the DDB file. Auto-detected if None (default).
            qptbounds: Boundaries of the path. If None, the path is generated from an internal database
                depending on the input structure.
            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.

        Returns:
            A GrunsNcFile object.
        """

        if len(ddb_list) % 2 != 1:
            raise ValueError("An odd number of ddb file paths should be provided")

        ddbs = [DdbFile(d) for d in ddb_list]
        ddbs = sorted(ddbs, key=lambda d: d.structure.volume)
        iv0 = int((len(ddbs) - 1) / 2)
        ddb0 = ddbs[iv0]
        # update list of paths with absolute paths in the correct order
        ddb_list = [d.filepath for d in ddbs]

        if ngqpt is None: ngqpt = ddb0.guessed_ngqpt

        if lo_to_splitting == "automatic":
            lo_to_splitting = ddb0.has_lo_to_data() and dipdip != 0

        if lo_to_splitting and not ddb0.has_lo_to_data():
            cprint("lo_to_splitting is True but Emacro and Becs are not available in DDB: %s" % ddb0.filepath, "yellow")

        inp = AnaddbInput.phbands_and_dos(
            ddb0.structure, ngqpt=ngqpt, ndivsm=ndivsm, nqsmall=nqsmall, qppa=qppa, line_density=line_density,
            q1shft=(0, 0, 0), qptbounds=qptbounds, asr=asr, chneut=chneut, dipdip=dipdip, dos_method=dos_method,
            lo_to_splitting=lo_to_splitting, anaddb_kwargs=anaddb_kwargs)

        inp["gruns_ddbs"] = ['"'+p+'"\n' for p in ddb_list]
        inp["gruns_nddbs"] = len(ddb_list)

        task = AnaddbTask.temp_shell_task(inp, ddb_node=ddb0.filepath, workdir=workdir, manager=manager, mpi_procs=mpi_procs)

        if verbose:
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise ddb0.AnaddbError(task=task, report=report)

        gruns = cls.from_file(os.path.join(task.workdir, "run.abo_GRUNS.nc"))

        return gruns
Ejemplo n.º 10
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)
Ejemplo n.º 11
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
Ejemplo n.º 12
0
    def anaget_phmodes_at_qpoint(self,
                                 qpoint=None,
                                 asr=2,
                                 chneut=1,
                                 dipdip=1,
                                 workdir=None,
                                 manager=None,
                                 verbose=0,
                                 lo_to_splitting=False,
                                 directions=None,
                                 anaddb_kwargs=None):
        """
        Execute anaddb to compute phonon modes at the given q-point.

        Args:
            qpoint: Reduced coordinates of the qpoint where phonon modes are computed.
            asr, chneut, dipdp: Anaddb input variable. See official documentation.
            workdir: Working directory. If None, a temporary directory is created.
            manager: :class:`TaskManager` object. If None, the object is initialized from the configuration file
            verbose: verbosity level. Set it to a value > 0 to get more information
            lo_to_splitting: if True the LO-TO splitting will be calculated if qpoint==Gamma and the non_anal_directions
                non_anal_phfreqs attributes will be added to the returned object
            directions: list of 3D directions along which the LO-TO splitting will be calculated. If None the three
                cartesian direction will be used
            anaddb_kwargs: additional kwargs for anaddb

        Return:
            :class:`PhononBands` object.
        """
        if qpoint is None:
            qpoint = self.qpoints[0]
            if len(self.qpoints) != 1:
                raise ValueError(
                    "%s contains %s qpoints and the choice is ambiguous.\n"
                    "Please specify the qpoint." % (self, len(self.qpoints)))

        # Check if qpoint is in the DDB.
        try:
            self.qindex(qpoint)
        except:
            raise ValueError("input qpoint %s not in ddb.qpoints:%s\n" %
                             (qpoint, self.qpoints))

        inp = AnaddbInput.modes_at_qpoint(self.structure,
                                          qpoint,
                                          asr=asr,
                                          chneut=chneut,
                                          dipdip=dipdip,
                                          lo_to_splitting=lo_to_splitting,
                                          directions=directions,
                                          anaddb_kwargs=anaddb_kwargs)

        task = AnaddbTask.temp_shell_task(inp,
                                          ddb_node=self.filepath,
                                          workdir=workdir,
                                          manager=manager)

        if verbose:
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here
        task.start_and_wait(autoparal=False)
        report = task.get_event_report()
        if not report.run_completed:
            raise self.AnaddbError(task=task, report=report)

        with task.open_phbst() as ncfile:
            if lo_to_splitting and np.allclose(qpoint, [0, 0, 0]):
                ncfile.phbands.read_non_anal_from_file(
                    os.path.join(task.workdir, "anaddb.nc"))

            return ncfile.phbands
Ejemplo n.º 13
0
    def add_phonon_works_and_build(self):
        """
        Get relaxed structures from the tasks, build Phonons works with new structures.
        Add works to the flow and build new directories.
        """
        ddb_paths, struct_middle, middle_idx = [], None, None
        relaxed_structs = []

        for i, task in enumerate(self.relax_tasks):
            relaxed_structure = task.get_final_structure()
            relaxed_structs.append(relaxed_structure)
            if i == len(self.relax_tasks) // 2:
                middle_idx, struct_middle = i, relaxed_structure

            # work to compute phonons with new structure.
            gsinp_vol = self.gs_inp.new_with_structure(relaxed_structure)
            work = PhononWork.from_scf_input(gsinp_vol, self.ngqpt, is_ngqpt=True, tolerance=self.tolerance,
                                             with_becs=self.with_becs, ddk_tolerance=self.ddk_tolerance)
            # Add it to the flow.
            self.flow.register_work(work)

            ddb_paths.append(work.outdir.path_in("out_DDB"))

        # Write Anaddb input file to compute Gruneisen parameters in flow.outdata.
        from abipy.abio.inputs import AnaddbInput
        anaddb_inp = AnaddbInput.phbands_and_dos(struct_middle, self.ngqpt, nqsmall=20, ndivsm=20,
                                                 chneut=1 if self.with_becs else 0,
                                                 dipdip=1 if self.with_becs else 0,
                                                 lo_to_splitting=self.with_becs,
                                                 comment="Anaddb input file for Grunesein parameters")
        # Add DDB files for Gruns
        anaddb_inp["gruns_nddbs"] = len(ddb_paths)
        anaddb_inp["gruns_ddbs"] = "\n" + "\n".join('"%s"' % p for p in ddb_paths)
        in_path = self.flow.outdir.path_in("anaddb_gruns.in")
        anaddb_inp.write(in_path)

        files_file = []
        app = files_file.append
        app(in_path)                                        # 1) Path of the input file
        app(self.flow.outdir.path_in("anaddb_gruns.out"))   # 2) Path of the output file
        app(ddb_paths[middle_idx])                          # 3) Input derivative database (not used if Gruns)
        for i in range(4):
            app("FOOBAR")

        with open(self.flow.outdir.path_in("anaddb_gruns.files"), "wt") as fh:
            fh.write("\n".join(files_file))

        #with_ebands = False
        #if with_ebands:
        #    bands_work = Work(manager=self.manager)
        #    for i, structure in enumerate(relaxed_structs):
        #        nscf_inp = self.gs_inp.new_with_structure(structure)
        #        nscf_inp.pop_tolerances()
        #        nscf_inp.set_kpath(ndivsm, kptbounds=None, iscf=-2)
        #        nscf_inp["tolwfr"] = 1e-18
        #        work.register_nscf_task(nscf_inp, deps={self.relax_tasks[i]: "DEN"})

        #    # Add it to the flow.
        #    self.flow.register_work(work)

        # Allocate new works and update the pickle database.
        self.flow.allocate()
        self.flow.build_and_pickle_dump()
Ejemplo n.º 14
0
 def test_AnaDdbAbinitTask(self):
     ana_inp = AnaddbInput.phbands_and_dos(self.si_structure, ngqpt=[4,4,4], nqsmall=10)
     task = abinit_tasks.AnaDdbAbinitTask(ana_inp)
     task.to_dict()
     self.assertFwSerializable(task)
Ejemplo n.º 15
0
    def from_ddb_list(cls, ddb_list, nqsmall=10, qppa=None, ndivsm=20, line_density=None, asr=2, chneut=1, dipdip=1,
                     dos_method="tetra", lo_to_splitting="automatic", ngqpt=None, qptbounds=None, anaddb_kwargs=None,
                     verbose=0, mpi_procs=1, workdir=None, manager=None):
        """
        Execute anaddb to compute generate the object from a list of ddbs.

        Args:
            ddb_list: A list with the paths to the ddb_files at different volumes. There should be an odd number of
                DDB files and the volume increment must be constant. The DDB files will be ordered according to the
                volume of the unit cell and the middle one will be considered as the DDB at the relaxed volume.
            nqsmall: Defines the homogeneous q-mesh used for the DOS. Gives the number of divisions
                used to sample the smallest lattice vector. If 0, DOS is not computed and
                (phbst, None) is returned.
            qppa: Defines the homogeneous q-mesh used for the DOS in units of q-points per reciprocal atom.
                Overrides nqsmall.
            ndivsm: Number of division used for the smallest segment of the q-path.
            line_density: Defines the a density of k-points per reciprocal atom to plot the phonon dispersion.
                Overrides ndivsm.
            asr, chneut, dipdip: Anaddb input variable. See official documentation.
            dos_method: Technique for DOS computation in  Possible choices: "tetra", "gaussian" or "gaussian:0.001 eV".
                In the later case, the value 0.001 eV is used as gaussian broadening.
            lo_to_splitting: Allowed values are [True, False, "automatic"]. Defaults to "automatic"
                If True the LO-TO splitting will be calculated and the non_anal_directions
                and the non_anal_phfreqs attributes will be addeded to the phonon band structure.
                "automatic" activates LO-TO if the DDB file contains the dielectric tensor and Born effective charges.
            ngqpt: Number of divisions for the q-mesh in the DDB file. Auto-detected if None (default).
            qptbounds: Boundaries of the path. If None, the path is generated from an internal database
                depending on the input structure.
            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.

        Returns:
            A GrunsNcFile object.
        """

        if len(ddb_list) % 2 != 1:
            raise ValueError("An odd number of ddb file paths should be provided")

        ddbs = [DdbFile(d) for d in ddb_list]
        ddbs = sorted(ddbs, key=lambda d: d.structure.volume)
        iv0 = int((len(ddbs) - 1) / 2)
        ddb0 = ddbs[iv0]
        # update list of paths with absolute paths in the correct order
        ddb_list = [d.filepath for d in ddbs]

        if ngqpt is None: ngqpt = ddb0.guessed_ngqpt

        if lo_to_splitting == "automatic":
            lo_to_splitting = ddb0.has_lo_to_data() and dipdip != 0

        if lo_to_splitting and not ddb0.has_lo_to_data():
            cprint("lo_to_splitting is True but Emacro and Becs are not available in DDB: %s" % ddb0.filepath, "yellow")

        inp = AnaddbInput.phbands_and_dos(
            ddb0.structure, ngqpt=ngqpt, ndivsm=ndivsm, nqsmall=nqsmall, qppa=qppa, line_density=line_density,
            q1shft=(0, 0, 0), qptbounds=qptbounds, asr=asr, chneut=chneut, dipdip=dipdip, dos_method=dos_method,
            lo_to_splitting=lo_to_splitting, anaddb_kwargs=anaddb_kwargs)

        inp["gruns_ddbs"] = ['"'+p+'"\n' for p in ddb_list]
        inp["gruns_nddbs"] = len(ddb_list)

        task = AnaddbTask.temp_shell_task(inp, ddb_node=ddb0.filepath, workdir=workdir, manager=manager, mpi_procs=mpi_procs)

        if verbose:
            print("ANADDB INPUT:\n", inp)
            print("workdir:", task.workdir)

        # Run the task here.
        task.start_and_wait(autoparal=False)

        report = task.get_event_report()
        if not report.run_completed:
            raise ddb0.AnaddbError(task=task, report=report)

        gruns = cls.from_file(os.path.join(task.workdir, "run.abo_GRUNS.nc"))

        return gruns