Beispiel #1
0
def bandstructure(workdir, runmode, structure, pseudos, scf_kppa, nscf_nband,
                  ndivsm, accuracy="normal", spin_mode="polarized",
                  smearing="fermi_dirac:0.1 eV", charge=0.0, scf_solver=None,
                  dos_kppa=None):

    scf_ksampling = KSampling.automatic_density(structure, scf_kppa,
                                                chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge,
                               scf_solver=scf_solver)

    nscf_ksampling = KSampling.path_from_structure(ndivsm, structure)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband)

    dos_strategy = None

    if dos_kppa is not None:
        raise NotImplementedError("DOS must be tested")
        dos_ksampling = KSampling.automatic_density(structure, kppa,
                                                    chksymbreak=0)
        dos_strategy = NscfStrategy(scf_strategy, dos_ksampling, nscf_nband,
                                    nscf_solver=None)

    return BandStructure(workdir, runmode, scf_strategy, nscf_strategy,
                         dos_strategy=dos_strategy)
Beispiel #2
0
def bandstructure(workdir, runmode, structure, pseudos, scf_kppa, nscf_nband,
                  ndivsm, accuracy="normal", spin_mode="polarized",
                  smearing="fermi_dirac:0.1 eV", charge=0.0, scf_solver=None,
                  dos_kppa=None):
    """
    Returns a Work object that computes that bandstructure of the material.

    Args:
        workdir:
            Working directory.
        runmode:
            `RunMode` instance.
        structure:
            Pymatgen structure.
        pseudos:
            List of `Pseudo` objects.
        scf_kppa:
            Defines the sampling used for the SCF run.
        nscf_nband:
            Number of bands included in the NSCF run.
        ndivs:
            Number of divisions used to sample the smallest segment of the k-path.
        accuracy:
            Accuracy of the calculation.
        spin_mode:
            Spin polarization.
        smearing:
            Smearing technique.
        charge:
            Electronic charge added to the unit cell.
        scf_solver:
            Algorithm used for solving of the SCF cycle.
        dos_kppa
            Defines the k-point sampling used for the computation of the DOS 
            (None if DOS is not wanted).
    """
    scf_ksampling = KSampling.automatic_density(structure, scf_kppa,
                                                chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge,
                               scf_solver=scf_solver)

    nscf_ksampling = KSampling.path_from_structure(ndivsm, structure)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband)

    dos_strategy = None

    if dos_kppa is not None:
        raise NotImplementedError("DOS must be tested")
        dos_ksampling = KSampling.automatic_density(structure, kppa,
                                                    chksymbreak=0)
        dos_strategy = NscfStrategy(scf_strategy, dos_ksampling, nscf_nband,
                                    nscf_solver=None)

    return BandStructure(workdir, runmode, scf_strategy, nscf_strategy,
                         dos_strategy=dos_strategy)
Beispiel #3
0
    def __init__(self,
                 scf_task,
                 ksampling=1000,
                 nscf_bands=None,
                 nscf_algorithm=None,
                 deps={},
                 task_id=None,
                 **extra_abivars):

        if task_id:
            self.task_id = task_id
        else:
            self.task_id = id(self)

        extra_abivars.pop('_fw_name', None)

        self.scf_task = scf_task
        self.ksampling = ksampling
        self.nscf_bands = nscf_bands
        self.nscf_algorithm = nscf_algorithm
        self.extra_abivars = extra_abivars
        self.deps = self.parse_deps(deps)

        if isinstance(ksampling, int):
            ksampling = KSampling.automatic_density(scf_task.structure,
                                                    ksampling)

        strategy = NscfStrategy(scf_task.abitask.strategy, ksampling,
                                nscf_bands, nscf_algorithm, **extra_abivars)

        self.abitask = NscfTask(strategy,
                                workdir=None,
                                manager=abilab.TaskManager.from_user_config(),
                                deps={})
Beispiel #4
0
    def scf_ph_inputs(structure, pseudos, **kwargs):
        """
        This function constructs the input files for the phonon calculation:
        GS input + the input files for the phonon calculation.
        kwargs:
        ecut: the ecut at which the input is generated
        kppa: kpoint per atom
        smearing: is removed
        qpt: optional, list of qpoints. if not present gamma is added
        the rest are passed as abinit input variables
        """

        qpoints = kwargs.pop('qpt', [0.00000000E+00,  0.00000000E+00,  0.00000000E+00])
        qpoints = np.reshape(qpoints, (-1, 3))

        # Global variables used both for the GS and the DFPT run.
        kppa = kwargs.pop('kppa')
        ksampling = KSampling.automatic_density(structure, kppa, chksymbreak=0)
        try:
            kwargs.pop('accuracy')
        except KeyError:
            pass
        kwargs.pop('smearing')
        # to be applicable to all systems we treat all as is they were metals
        # some systems have a non primitive cell to allow for a anti ferromagnetic structure > chkprim = 0
        global_vars = dict(ksampling.to_abivars(), tsmear=0.005, occopt=7, nstep=200, ecut=12.0, paral_kgb=0, chkprim=0)
        global_vars.update(**kwargs)
        # if not tolwfr is specified explicitly we remove any other tol and put tolwfr = 1e-16
        tolwfr = 1e-20
        for k in global_vars.keys():
            if 'tol' in k:
                if k == 'tolwfr':
                    tolwfr = global_vars.pop(k)
                else:
                    global_vars.pop(k)

        global_vars['tolwfr'] = tolwfr
        #global_vars.pop('#comment')
        electrons = structure.num_valence_electrons(pseudos)
        global_vars.update(nband=electrons)
        global_vars.update(nbdbuf=int(electrons/4))

        multi = abilab.MultiDataset(structure=structure, pseudos=pseudos, ndtset=1+len(qpoints))
        multi.set_vars(global_vars)

        rfasr = kwargs.pop('rfasr', 2)

        for i, qpt in enumerate(qpoints):
            # Response-function calculation for phonons.
            # rfatpol=[1, natom],  # Set of atoms to displace.
            # rfdir=[1, 1, 1],     # Along this set of reduced coordinate axis
            multi[i+1].set_vars(nstep=200, iscf=7, rfphon=1, nqpt=1, qpt=qpt, kptopt=2, rfasr=rfasr, 
                              rfatpol=[1, len(structure)], rfdir=[1, 1, 1])

            # rfasr = 1 is not correct
            # response calculations can not be restarted > nstep = 200, a problem to solve here is that abinit continues
            # happily even is NaN are produced ... TODO fix abinit

        # Split input into gs_inp and ph_inputs
        return multi.split_datasets()
Beispiel #5
0
    def strategy_with_ecut(self, ecut):
        """Return a Strategy instance with given cutoff energy ecut."""

        # Define the system: one atom in a box of lenghts acell.
        boxed_atom = AbiStructure.boxed_atom(self.pseudo, acell=self.acell)

        # Gamma-only sampling.
        gamma_only = KSampling.gamma_only()

        # Setup electrons.
        electrons = Electrons(spin_mode=self.spin_mode, smearing=self.smearing)

        # Don't write WFK files.
        extra_abivars = {
            "ecut" : ecut,
            "prtwf": 0,
            "toldfe": self.toldfe,
        }

        strategy = ScfStrategy(boxed_atom, self.pseudo, gamma_only,
                               spin_mode=self.spin_mode, smearing=self.smearing,
                               charge=0.0, scf_algorithm=None,
                               use_symmetries=True, **extra_abivars)

        return strategy
Beispiel #6
0
    def __init__(self, structure, struct_type, pseudo, ecut=None, pawecutdg=None, ngkpt=(8, 8, 8),
                 spin_mode="unpolarized", toldfe=1.e-9, smearing="fermi_dirac:0.001 Ha",
                 accuracy="normal", ecutsm=0.05, chksymbreak=0,
                 workdir=None, manager=None, **kwargs):
        """
        Build a :class:`Work` for the computation of the relaxed lattice parameter.

        Args:   
            structure: :class:`Structure` object 
            structure_type: fcc, bcc 
            pseudo: String with the name of the pseudopotential file or :class:`Pseudo` object.
            ecut: Cutoff energy in Hartree
            ngkpt: MP divisions.
            spin_mode: Spin polarization mode.
            toldfe: Tolerance on the energy (Ha)
            smearing: Smearing technique.
            workdir: String specifing the working directory.
            manager: :class:`TaskManager` responsible for the submission of the tasks.
        """
        super(GbrvRelaxAndEosWork, self).__init__(workdir=workdir, manager=manager)
        self.struct_type = struct_type
        self.accuracy = accuracy

        # nband must be large enough to accomodate fractional occupancies.
        fband = kwargs.pop("fband", None)
        self._pseudo = Pseudo.as_pseudo(pseudo)
        nband = gbrv_nband(self.pseudo)

        # Set extra_abivars.
        self.extra_abivars = dict(
            ecut=ecut,
            pawecutdg=pawecutdg,
            toldfe=toldfe,
            prtwf=0,
            #ecutsm=0.5,
            nband=nband,
            #paral_kgb=paral_kgb
        )
                                       
        self.extra_abivars.update(**kwargs)
        self.ecut = ecut
        self.smearing = Smearing.as_smearing(smearing)

        # Kpoint sampling: shiftk depends on struct_type
        shiftk = {"fcc": [0, 0, 0], "bcc": [0.5, 0.5, 0.5]}.get(struct_type)
        #ngkpt = (1,1,1)
        self.ksampling = KSampling.monkhorst(ngkpt, chksymbreak=chksymbreak, shiftk=shiftk)
        self.spin_mode = SpinMode.as_spinmode(spin_mode)
        relax_algo = RelaxationMethod.atoms_and_cell()

        #self.relax_input = RelaxStrategy(structure, pseudo, self.ksampling, relax_algo, 
        #                                 accuracy=accuracy, spin_mode=spin_mode, smearing=smearing, **self.extra_abivars)

        inp = abilab.AbinitInput(structure, pseudo)
        inp.add_abiobjects(self.ksampling, relax_algo, self.spin_mode, self.smearing)
        inp.set_vars(self.extra_abivars)

        # Register structure relaxation task.
        self.relax_task = self.register_relax_task(inp)
Beispiel #7
0
def g0w0_with_ppmodel(workdir, runmode, structure, pseudos, scf_kppa,
                      nscf_nband, ecuteps, ecutsigx, accuracy="normal",
                      spin_mode="polarized", smearing="fermi_dirac:0.1 eV",
                      ppmodel="godby", charge=0.0, scf_solver=None,
                      inclvkb=2, sigma_nband=None, scr_nband=None):

    # TODO: Cannot use istwfk != 1.
    extra_abivars = {"istwfk": "*1"}

    scf_ksampling = KSampling.automatic_density(structure, scf_kppa,
                                                chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge,
                               scf_solver=None, **extra_abivars)

    nscf_ksampling = KSampling.automatic_density(structure, 1, chksymbreak=0)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband,
                                 **extra_abivars)

    if scr_nband is None:
        scr_nband = nscf_nband

    if sigma_nband is None:
        sigma_nband = nscf_nband

    screening = Screening(ecuteps, scr_nband, w_type="RPA", sc_mode="one_shot",
                          freq_mesh=None, hilbert_transform=None, ecutwfn=None,
                          inclvkb=inclvkb)

    self_energy = SelfEnergy("gw", "one_shot", sigma_nband, ecutsigx, screening,
                             ppmodel=ppmodel)

    scr_strategy = ScreeningStrategy(scf_strategy, nscf_strategy, screening,
                                     **extra_abivars)

    sigma_strategy = SelfEnergyStrategy(scf_strategy, nscf_strategy,
                                        scr_strategy, self_energy,
                                        **extra_abivars)

    return GW_Workflow(workdir, runmode, scf_strategy, nscf_strategy,
                       scr_strategy, sigma_strategy)
Beispiel #8
0
    def __init__(self, structure, pseudos, ksampling=1000, relax_algo="atoms_and_cell", accuracy="normal",
                 spin_mode="polarized", smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None,
                 use_symmetries=True, ksampling_band=8, nscf_bands=None, nscf_algorithm=None, autoparal=False,
                 folder=None, **extra_abivars):

        # workflow to obtain the density
        if relax_algo in relaxation_methods.keys():
            if relax_algo == "atoms_and_cell":
                dens_wf = RelaxFWWorkflow(structure=structure, pseudos=pseudos, ksampling=ksampling, accuracy=accuracy,
                                          spin_mode=spin_mode, smearing=smearing, charge=charge,
                                          scf_algorithm=scf_algorithm, autoparal=autoparal, folder=folder,
                                          **extra_abivars)
                last_task = dens_wf.ioncell_task
            else:
                dens_wf = RelaxAtomsFWWorkflow(structure=structure, pseudos=pseudos, ksampling=ksampling,
                                               accuracy=accuracy, spin_mode=spin_mode, smearing=smearing, charge=charge,
                                               scf_algorithm=scf_algorithm, autoparal=autoparal, folder=folder,
                                               **extra_abivars)
                last_task = dens_wf.task
            deps = {id(last_task): 'DEN structure'}
        else:
            if relax_algo not in (None, 'scf', 'scf_only', 'no_relax'):
                logger.warning('relax_algo value "%s" not recognized. Perorming a scf calculation.' % relax_algo)

            dens_wf = ScfFWWorkflow(structure=structure, pseudos=pseudos, ksampling=ksampling, accuracy=accuracy,
                                    spin_mode=spin_mode, smearing=smearing, charge=charge, scf_algorithm=scf_algorithm,
                                    use_symmetries=use_symmetries, autoparal=autoparal, folder=folder, **extra_abivars)
            last_task = dens_wf.task
            deps = {id(last_task): 'DEN'}

        # Create the ksampling based on high symmetry lines of the structure
        if isinstance(ksampling_band, int):
            # ksampling_band = KSampling.automatic_density(structure, 100)
            ksampling_band = KSampling.path_from_structure(ksampling_band, structure)

        # Create the nscf FW
        nscf_task = NscfStrategyFireTask(scf_task=last_task, ksampling=ksampling_band, nscf_bands=nscf_bands,
                                         nscf_algorithm=nscf_algorithm, deps=deps, **extra_abivars)

        spec = {'create_file': 'band_structure'}
        if folder:
            spec['_launch_dir'] = os.path.join(folder, 'band_structure')

        nscf_fw = Firework(nscf_task, spec=spec)

        # Expand the first part to get the proper list of FWs and links
        fws, links = parse_workflow([dens_wf.wf, nscf_fw], {dens_wf.wf: [nscf_fw]})

        self.wf = Workflow(fws, links)
Beispiel #9
0
    def add_task_with_ecut(self, ecut):
        """Register a new task with cutoff energy ecut."""
        # One atom in a box of lenghts acell.
        inp = abilab.AbinitInput(structure=Structure.boxed_atom(self.pseudo, acell=self.acell), 
                                 pseudos=self.pseudo)

        # Gamma-only sampling.
        inp.add_abiobjects(self.spin_mode, self.smearing, KSampling.gamma_only())

        inp.set_vars(
            ecut=ecut,
            toldfe=self.toldfe,
            prtwf=1,
        )

        self.ecuts.append(ecut)
        self.register_scf_task(inp)
Beispiel #10
0
    def __init__(self, scf_task, ksampling=1000, nscf_bands=None, nscf_algorithm=None, deps={},
                 task_id=None, **extra_abivars):

        if task_id:
            self.task_id = task_id
        else:
            self.task_id = id(self)

        extra_abivars.pop('_fw_name', None)

        self.scf_task = scf_task
        self.ksampling = ksampling
        self.nscf_bands = nscf_bands
        self.nscf_algorithm = nscf_algorithm
        self.extra_abivars = extra_abivars
        self.deps = self.parse_deps(deps)

        if isinstance(ksampling, int):
            ksampling = KSampling.automatic_density(scf_task.structure, ksampling)

        strategy = NscfStrategy(scf_task.abitask.strategy, ksampling, nscf_bands, nscf_algorithm, **extra_abivars)

        self.abitask = NscfTask(strategy, workdir=None, manager=abilab.TaskManager.from_user_config(), deps={})
Beispiel #11
0
def bse_with_mdf(structure, pseudos, scf_kppa, nscf_nband, nscf_ngkpt, nscf_shiftk, 
                 ecuteps, bs_loband, bs_nband, soenergy, mdf_epsinf, 
                 exc_type="TDA", bs_algo="haydock", accuracy="normal", spin_mode="polarized", 
                 smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None, workdir=None, manager=None, 
                 **extra_abivars):
    """
    Returns a `Workflow` object that performs a GS + NSCF + Bethe-Salpeter calculation.
    The self-energy corrections are approximated with the scissors operator. The screening
    in modeled by the model dielectric function.

    Args:
        structure:
            `Structure` object.
        pseudos:
            List of `Pseudo` objects.
        scf_kppa:
            Defines the sampling used for the SCF run.
        nscf_nband:
            Number of bands included in the NSCF run.
        nscf_ngkpt:
            Division of the k-mesh used for the NSCF and the BSE run.
        nscf_shiftk:
            Shifts used for the NSCF and the BSE run.
        ecuteps:
            Cutoff energy [Ha] for the screening matrix.
        bs_loband:
            Index of the first occupied band included the e-h basis set
            (ABINIT convention i.e. first band starts at 1).
            Can be scalar or array of shape (nsppol,)
        bs_nband:
            Highest band idex used for the construction of the e-h basis set.
        soenergy:
            Scissor energy in Hartree.
        mdf_epsinf:
            Value of the macroscopic dielectric function used in expression for the model dielectric function.
        exc_type:
            Approximation used for the BSE Hamiltonian (Tamm-Dancoff or coupling).
        bs_algo:
            Algorith for the computatio of the macroscopic dielectric function.
        accuracy:
            Accuracy of the calculation.
        spin_mode:
            Spin polarization.
        smearing:
            Smearing technique.
        charge:
            Electronic charge added to the unit cell.
        scf_algorithm:
            Algorithm used for solving the SCF cycle.
        workdir:
            Working directory.
        manager:
            `TaskManger` instance.
        extra_abivars:
            Dictionary with extra variables passed to ABINIT.
    """
    # TODO: Cannot use istwfk != 1.
    if "istwfk" not in extra_abivars:
        extra_abivars["istwfk"] = "*1"

    # Ground-state strategy.
    scf_ksampling = KSampling.automatic_density(structure, scf_kppa, chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge, scf_algorithm=None, **extra_abivars)

    # NSCF calculation with the randomly-shifted k-mesh.
    nscf_ksampling = KSampling.monkhorst(nscf_ngkpt, shiftk=nscf_shiftk, chksymbreak=0)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband, **extra_abivars)

    # Strategy for the BSE calculation.
    exc_ham = ExcHamiltonian(bs_loband, bs_nband, soenergy, coulomb_mode="model_df", ecuteps=ecuteps, 
                             spin_mode=spin_mode, mdf_epsinf=mdf_epsinf, exc_type=exc_type, algo=bs_algo,
                             bs_freq_mesh=None, with_lf=True, zcut=None)

    bse_strategy = MDFBSE_Strategy(scf_strategy, nscf_strategy, exc_ham, **extra_abivars)
    raise NotImplementedError("")

    return BSEMDF_Workflow(scf_strategy, nscf_strategy, bse_strategy, workdir=workdir, manager=manager)
Beispiel #12
0
def g0w0_with_ppmodel(structure, pseudos, scf_kppa, nscf_nband, ecuteps, ecutsigx, 
                      accuracy="normal", spin_mode="polarized", smearing="fermi_dirac:0.1 eV",
                      ppmodel="godby", charge=0.0, scf_algorithm=None, inclvkb=2, scr_nband=None, 
                      sigma_nband=None, gw_qprange=1, workdir=None, manager=None, **extra_abivars):
    """
    Returns a Work object that performs G0W0 calculations for the given the material.

    Args:
        structure:
            Pymatgen structure.
        pseudos:
            List of `Pseudo` objects.
        scf_kppa:
            Defines the sampling used for the SCF run.
        nscf_nband:
            Number of bands included in the NSCF run.
        ecuteps:
            Cutoff energy [Ha] for the screening matrix.
        ecutsigx:
            Cutoff energy [Ha] for the exchange part of the self-energy.
        accuracy:
            Accuracy of the calculation.
        spin_mode:
            Spin polarization.
        smearing:
            Smearing technique.
        ppmodel:
            Plasmonpole technique.
        charge:
            Electronic charge added to the unit cell.
        scf_algorithm:
            Algorithm used for solving of the SCF cycle.
        inclvkb:
            Treatment of the dipole matrix elements (see abinit variable).
        scr_nband:
            Number of bands used to compute the screening (default is nscf_nband)
        sigma_nband:
            Number of bands used to compute the self-energy (default is nscf_nband)
        gw_qprange:
            Option for the automatic selection of k-points and bands for GW corrections.
            See Abinit docs for more detail. The default value makes the code computie the 
            QP energies for all the point in the IBZ and one band above and one band below the Fermi level.
        workdir:
            Working directory.
        manager:
            `TaskManager` instance.
        extra_abivars
            Dictionary with extra variables passed to ABINIT.
    """
    # TODO: Cannot use istwfk != 1.
    if "istwfk" not in extra_abivars:
        extra_abivars["istwfk"] = "*1"

    scf_ksampling = KSampling.automatic_density(structure, scf_kppa, chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge,
                               scf_algorithm=None, **extra_abivars)

    nscf_ksampling = KSampling.automatic_density(structure, scf_kppa, chksymbreak=0)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband, **extra_abivars)

    if scr_nband is None: scr_nband = nscf_nband
    if sigma_nband is None: sigma_nband = nscf_nband

    screening = Screening(ecuteps, scr_nband, w_type="RPA", sc_mode="one_shot",
                          hilbert=None, ecutwfn=None, inclvkb=inclvkb)

    self_energy = SelfEnergy("gw", "one_shot", sigma_nband, ecutsigx, screening,
                             ppmodel=ppmodel)

    scr_strategy = ScreeningStrategy(scf_strategy, nscf_strategy, screening, **extra_abivars)

    sigma_strategy = SelfEnergyStrategy(scf_strategy, nscf_strategy, scr_strategy, self_energy,
                                        **extra_abivars)

    return G0W0_Workflow(scf_strategy, nscf_strategy, scr_strategy, sigma_strategy, 
                         workdir=workdir, manager=manager)
Beispiel #13
0
    def __init__(self, structure, pseudo, kppa, connect,
                 ecut=None, pawecutdg=None, ecutsm=0.5,
                 spin_mode="polarized", toldfe=1.e-9, smearing="fermi_dirac:0.1 eV",
                 accuracy="normal", chksymbreak=0, workdir=None, manager=None, **kwargs):
        """
        Build a :class:`Work` for the computation of the deltafactor.

        Args:   
            structure: :class:`Structure` object
            pseudo: String with the name of the pseudopotential file or :class:`Pseudo` object.
            kppa: Number of k-points per atom.
            connect: True if the SCF run should be initialized from the previous run.
            spin_mode: Spin polarization mode.
            toldfe: Tolerance on the energy (Ha)
            smearing: Smearing technique.
            workdir: String specifing the working directory.
            manager: :class:`TaskManager` responsible for the submission of the tasks.
        """
        super(DeltaFactorWork, self).__init__(workdir=workdir, manager=manager)

        self._pseudo = Pseudo.as_pseudo(pseudo)

        spin_mode = SpinMode.as_spinmode(spin_mode)
        smearing = Smearing.as_smearing(smearing)

        # Compute the number of bands from the pseudo and the spin-polarization.
        # Add 6 bands to account for smearing.
        #nval = structure.num_valence_electrons(self.pseudo)
        #spin_fact = 2 if spin_mode.nsppol == 2 else 1
        #nband = int(nval / spin_fact) + 6

        # Set extra_abivars
        self.ecut, self.pawecutdg = ecut, pawecutdg

        extra_abivars = dict(
            ecut=ecut,
            pawecutdg=pawecutdg,
            ecutsm=ecutsm,
            toldfe=toldfe,
            #nband=nband,
            prtwf=0 if not connect else 1,
            #paral_kgb=paral_kgb,
            chkprim=0,
            nstep=200,
            #mem_test=0,
        )

        extra_abivars.update(**kwargs)
        self._input_structure = structure
        v0 = structure.volume

        # From 94% to 106% of the equilibrium volume.
        self.volumes = v0 * np.arange(94, 108, 2) / 100.

        for vol in self.volumes:
            new_lattice = structure.lattice.scale(vol)

            new_structure = Structure(new_lattice, structure.species, structure.frac_coords)

            ksampling = KSampling.automatic_density(new_structure, kppa, chksymbreak=chksymbreak)

            #scf_input = ScfStrategy(new_structure, self.pseudo, ksampling,
            #                        accuracy=accuracy, spin_mode=spin_mode,
            #                        smearing=smearing, **extra_abivars)

            scf_input = abilab.AbinitInput(structure=new_structure, pseudos=self.pseudo)
            scf_input.add_abiobjects(ksampling, smearing, spin_mode)
            scf_input.set_vars(extra_abivars)

            self.register_scf_task(scf_input)

        if connect:
            logger.info("Connecting SCF tasks using previous WFK file")
            middle = len(self.volumes) // 2
            filetype = "WFK"
            for i, task in enumerate(self[:middle]):
                task.add_deps({self[i + 1]: filetype})

            for i, task in enumerate(self[middle+1:]):
                task.add_deps({self[middle + i]: filetype})
Beispiel #14
0
def bse_with_mdf(structure, pseudos, scf_kppa, nscf_nband, nscf_ngkpt, nscf_shiftk, 
                 ecuteps, bs_loband, soenergy, mdf_epsinf, accuracy="normal", spin_mode="polarized", 
                 smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None, workdir=None, manager=None, 
                 **extra_abivars):
    """
    Returns a Work object that performs a GS + NSCF + Bethe-Salpeter calculation.
    The self-energy corrections are approximated with the scissors operator. The screening
    in modeled by the model dielectric function.

    Args:
        structure:
            Pymatgen structure.
        pseudos:
            List of `Pseudo` objects.
        scf_kppa:
            Defines the sampling used for the SCF run.
        nscf_nband:
            Number of bands included in the NSCF run.
        nscf_ngkpt:
            Division of the k-mesh used for the NSCF and the BSE run.
        nscf_shiftk:
            Shifts used for the NSCF and the BSE run.
        ecuteps:
            Cutoff energy [Ha] for the screening matrix.
        bs_loband:
            Index of the first occupied band included the e-h basis set
            (ABINIT convention i.e. first band starts at 1).
        soenergy:
            Scissor energy in Hartree
        mdf_epsinf:
            Value of the macroscopic dielectric function used in expression for the model dielectric function.
        accuracy:
            Accuracy of the calculation.
        spin_mode:
            Spin polarization.
        smearing:
            Smearing technique.
        charge:
            Electronic charge added to the unit cell.
        scf_algorithm:
            Algorithm used for solving the SCF cycle.
        workdir:
            Working directory.
        manager:
            `TaskManger` instance.
        extra_abivars:
            Dictionary with extra variables passed to ABINIT.
    """
    # TODO: Cannot use istwfk != 1.
    if "istwfk" not in extra_abivars:
        extra_abivars["istwfk"] = "*1"

    # Ground-state strategy.
    scf_ksampling = KSampling.automatic_density(structure, scf_kppa, chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge, scf_algorithm=None, **extra_abivars)

    # NSCF calculation on the randomly-shifted k-mesh.
    nscf_ksampling = KSampling.monkhorst(nscf_ngkpt, shiftk=nscf_shiftk, chksymbreak=0)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband, **extra_abivars)

    # Strategy for the BSE calculation.
    raise NotImplementedError("")
    # FIXME
    bs_nband = 6
    coulomb_mode = "model_df"
    bs_freq_mesh = [0, 2, 0.1]

    exc_ham = ExcHamiltonian(bs_loband, bs_nband, soenergy, coulomb_mode, ecuteps, bs_freq_mesh, 
                             mdf_epsinf=mdf_epsinf, exc_type="TDA", algo="haydock", with_lf=True, 
                             zcut=None)

    bse_strategy = MDFBSE_Strategy(scf_strategy, nscf_strategy, exc_ham, **extra_abivars)

    return BSEMDF_Workflow(scf_strategy, nscf_strategy, bse_strategy, workdir=workdir, manager=manager)
Beispiel #15
0
    def __init__(self, structure_or_cif, pseudo, kppa,
                 spin_mode="polarized", toldfe=1.e-8, smearing="fermi_dirac:0.1 eV",
                 accuracy="normal", ecut=None, ecutsm=0.05, chksymbreak=0, workdir=None, manager=None): 
                 # FIXME Hack in chksymbreack
        """
        Build a `Workflow` for the computation of the deltafactor.

        Args:   
            structure_or_cif:
                Structure objec or string with the path of the CIF file.
            pseudo:
                String with the name of the pseudopotential file or `Pseudo` object.` object.` object.` 
            kppa:
            spin_mode="polarized":
            toldfe=1.e-8:
            smearing="fermi_dirac:0.1 eV":
            workdir:
                String specifing the working directory.
            manager:
                `TaskManager` responsible for the submission of the tasks.
        """
        super(DeltaFactorWorkflow, self).__init__(workdir=workdir, manager=manager)

        if isinstance(structure_or_cif, Structure):
            structure = structure_or_cif
        else:
            # Assume CIF file
            structure = read_structure(structure_or_cif)

        self.pseudo = Pseudo.aspseudo(pseudo)

        structure = AbiStructure.asabistructure(structure)

        smearing = Smearing.assmearing(smearing)

        self._input_structure = structure

        v0 = structure.volume

        # From 94% to 106% of the equilibrium volume.
        self.volumes = v0 * np.arange(94, 108, 2) / 100.

        for vol in self.volumes:
            new_lattice = structure.lattice.scale(vol)

            new_structure = Structure(new_lattice, structure.species, structure.frac_coords)
            new_structure = AbiStructure.asabistructure(new_structure)

            extra_abivars = dict(
                ecutsm=ecutsm,
                toldfe=toldfe,
                prtwf=0,
                paral_kgb=0,
            )

            if ecut is not None:
                extra_abivars.update({"ecut": ecut})

            ksampling = KSampling.automatic_density(new_structure, kppa,
                                                    chksymbreak=chksymbreak)

            scf_input = ScfStrategy(new_structure, self.pseudo, ksampling,
                                    accuracy=accuracy, spin_mode=spin_mode,
                                    smearing=smearing, **extra_abivars)

            self.register(scf_input, task_class=ScfTask)
Beispiel #16
0
def bandstructure(structure, pseudos, scf_kppa, nscf_nband,
                  ndivsm, accuracy="normal", spin_mode="polarized",
                  smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None,
                  dos_kppa=None, workdir=None, manager=None, **extra_abivars):
    """
    Returns a Work object that computes that bandstructure of the material.

    Args:
        structure:
            Pymatgen structure.
        pseudos:
            List of `Pseudo` objects.
        scf_kppa:
            Defines the sampling used for the SCF run.
        nscf_nband:
            Number of bands included in the NSCF run.
        ndivs:
            Number of divisions used to sample the smallest segment of the
            k-path.
        accuracy:
            Accuracy of the calculation.
        spin_mode:
            Spin polarization.
        smearing:
            Smearing technique.
        charge:
            Electronic charge added to the unit cell.
        scf_algorithm:
            Algorithm used for solving of the SCF cycle.
        dos_kppa:
            Defines the k-point sampling used for the computation of the DOS 
            (None if DOS is not wanted).
        workdir:
            Working directory.
        manager:
            `TaskManager` instance.
        extra_abivars:
            Dictionary with extra variables passed to ABINIT.
    """
    # SCF calculation.
    scf_ksampling = KSampling.automatic_density(structure, scf_kppa, chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge,
                               scf_algorithm=scf_algorithm, **extra_abivars)

    # Band structure calculation.
    nscf_ksampling = KSampling.path_from_structure(ndivsm, structure)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband, **extra_abivars)

    # DOS calculation.
    dos_strategy = None
    if dos_kppa is not None:
        raise NotImplementedError("DOS must be tested")
        dos_ksampling = KSampling.automatic_density(structure, dos_kppa, chksymbreak=0)
        #dos_ksampling = KSampling.monkhorst(dos_ngkpt, shiftk=dos_shiftk, chksymbreak=0)

        dos_strategy = NscfStrategy(scf_strategy, dos_ksampling, nscf_nband, nscf_solver=None, **extra_abivars)

    return BandStructureWorkflow(scf_strategy, nscf_strategy, dos_inputs=dos_strategy, 
                                 workdir=workdir, manager=manager)
Beispiel #17
0
def g0w0_with_ppmodel(structure, pseudos, scf_kppa, nscf_nband, ecuteps, ecutsigx, 
                      accuracy="normal", spin_mode="polarized", smearing="fermi_dirac:0.1 eV",
                      ppmodel="godby", charge=0.0, scf_algorithm=None, inclvkb=2, scr_nband=None, 
                      sigma_nband=None, workdir=None, manager=None, **extra_abivars):
    """
    Returns a Work object that performs G0W0 calculations for the given the material.

    Args:
        structure:
            Pymatgen structure.
        pseudos:
            List of `Pseudo` objects.
        scf_kppa:
            Defines the sampling used for the SCF run.
        nscf_nband:
            Number of bands included in the NSCF run.
        ecuteps:
            Cutoff energy [Ha] for the screening matrix.
        ecutsigx:
            Cutoff energy [Ha] for the exchange part of the self-energy.
        accuracy:
            Accuracy of the calculation.
        spin_mode:
            Spin polarization.
        smearing:
            Smearing technique.
        ppmodel:
            Plasmonpole technique.
        charge:
            Electronic charge added to the unit cell.
        scf_algorithm:
            Algorithm used for solving of the SCF cycle.
        inclvkb:
            Treatment of the dipole matrix elements (see abinit variable).
        scr_nband:
            Number of bands used to compute the screening (default is nscf_nband)
        sigma_nband:
            Number of bands used to compute the self-energy (default is nscf_nband)
        workdir:
            Working directory.
        manager:
            `TaskManager` instance.
        extra_abivars
            Dictionary with extra variables passed to ABINIT.
    """
    # TODO: Cannot use istwfk != 1.
    if "istwfk" not in extra_abivars:
        extra_abivars["istwfk"] = "*1"

    scf_ksampling = KSampling.automatic_density(structure, scf_kppa, chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge,
                               scf_algorithm=None, **extra_abivars)

    nscf_ksampling = KSampling.automatic_density(structure, 1, chksymbreak=0)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband, **extra_abivars)

    if scr_nband is None:
        scr_nband = nscf_nband

    if sigma_nband is None:
        sigma_nband = nscf_nband

    screening = Screening(ecuteps, scr_nband, w_type="RPA", sc_mode="one_shot",
                          freq_mesh=None, hilbert_transform=None, ecutwfn=None,
                          inclvkb=inclvkb)

    self_energy = SelfEnergy("gw", "one_shot", sigma_nband, ecutsigx, screening,
                             ppmodel=ppmodel)

    scr_strategy = ScreeningStrategy(scf_strategy, nscf_strategy, screening, **extra_abivars)

    sigma_strategy = SelfEnergyStrategy(scf_strategy, nscf_strategy, scr_strategy, self_energy,
                                        **extra_abivars)

    return G0W0_Workflow(scf_strategy, nscf_strategy, scr_strategy, sigma_strategy, 
                         workdir=workdir, manager=manager)
Beispiel #18
0
    def __init__(self,
                 structure,
                 pseudos,
                 ksampling=1000,
                 relax_algo="atoms_and_cell",
                 accuracy="normal",
                 spin_mode="polarized",
                 smearing="fermi_dirac:0.1 eV",
                 charge=0.0,
                 scf_algorithm=None,
                 use_symmetries=True,
                 ksampling_band=8,
                 nscf_bands=None,
                 nscf_algorithm=None,
                 autoparal=False,
                 folder=None,
                 **extra_abivars):

        # workflow to obtain the density
        if relax_algo in relaxation_methods.keys():
            if relax_algo == "atoms_and_cell":
                dens_wf = RelaxFWWorkflow(structure=structure,
                                          pseudos=pseudos,
                                          ksampling=ksampling,
                                          accuracy=accuracy,
                                          spin_mode=spin_mode,
                                          smearing=smearing,
                                          charge=charge,
                                          scf_algorithm=scf_algorithm,
                                          autoparal=autoparal,
                                          folder=folder,
                                          **extra_abivars)
                last_task = dens_wf.ioncell_task
            else:
                dens_wf = RelaxAtomsFWWorkflow(structure=structure,
                                               pseudos=pseudos,
                                               ksampling=ksampling,
                                               accuracy=accuracy,
                                               spin_mode=spin_mode,
                                               smearing=smearing,
                                               charge=charge,
                                               scf_algorithm=scf_algorithm,
                                               autoparal=autoparal,
                                               folder=folder,
                                               **extra_abivars)
                last_task = dens_wf.task
            deps = {id(last_task): 'DEN structure'}
        else:
            if relax_algo not in (None, 'scf', 'scf_only', 'no_relax'):
                logger.warning(
                    'relax_algo value "%s" not recognized. Perorming a scf calculation.'
                    % relax_algo)

            dens_wf = ScfFWWorkflow(structure=structure,
                                    pseudos=pseudos,
                                    ksampling=ksampling,
                                    accuracy=accuracy,
                                    spin_mode=spin_mode,
                                    smearing=smearing,
                                    charge=charge,
                                    scf_algorithm=scf_algorithm,
                                    use_symmetries=use_symmetries,
                                    autoparal=autoparal,
                                    folder=folder,
                                    **extra_abivars)
            last_task = dens_wf.task
            deps = {id(last_task): 'DEN'}

        # Create the ksampling based on high symmetry lines of the structure
        if isinstance(ksampling_band, int):
            # ksampling_band = KSampling.automatic_density(structure, 100)
            ksampling_band = KSampling.path_from_structure(
                ksampling_band, structure)

        # Create the nscf FW
        nscf_task = NscfStrategyFireTask(scf_task=last_task,
                                         ksampling=ksampling_band,
                                         nscf_bands=nscf_bands,
                                         nscf_algorithm=nscf_algorithm,
                                         deps=deps,
                                         **extra_abivars)

        spec = {'create_file': 'band_structure'}
        if folder:
            spec['_launch_dir'] = os.path.join(folder, 'band_structure')

        nscf_fw = Firework(nscf_task, spec=spec)

        # Expand the first part to get the proper list of FWs and links
        fws, links = parse_workflow([dens_wf.wf, nscf_fw],
                                    {dens_wf.wf: [nscf_fw]})

        self.wf = Workflow(fws, links)
Beispiel #19
0
def bandstructure(structure, pseudos, scf_kppa, nscf_nband,
                  ndivsm, accuracy="normal", spin_mode="polarized",
                  smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None,
                  dos_kppa=None, workdir=None, manager=None, **extra_abivars):
    """
    Returns a Work object that computes that bandstructure of the material.

    Args:
        structure:
            Pymatgen structure.
        pseudos:
            List of `Pseudo` objects.
        scf_kppa:
            Defines the sampling used for the SCF run.
        nscf_nband:
            Number of bands included in the NSCF run.
        ndivs:
            Number of divisions used to sample the smallest segment of the
            k-path.
        accuracy:
            Accuracy of the calculation.
        spin_mode:
            Spin polarization.
        smearing:
            Smearing technique.
        charge:
            Electronic charge added to the unit cell.
        scf_algorithm:
            Algorithm used for solving of the SCF cycle.
        dos_kppa:
            Defines the k-point sampling used for the computation of the DOS 
            (None if DOS is not wanted).
        workdir:
            Working directory.
        manager:
            `TaskManager` instance.
        extra_abivars:
            Dictionary with extra variables passed to ABINIT.
    """
    # SCF calculation.
    scf_ksampling = KSampling.automatic_density(structure, scf_kppa, chksymbreak=0)

    scf_strategy = ScfStrategy(structure, pseudos, scf_ksampling,
                               accuracy=accuracy, spin_mode=spin_mode,
                               smearing=smearing, charge=charge,
                               scf_algorithm=scf_algorithm, **extra_abivars)

    # Band structure calculation.
    nscf_ksampling = KSampling.path_from_structure(ndivsm, structure)

    nscf_strategy = NscfStrategy(scf_strategy, nscf_ksampling, nscf_nband, **extra_abivars)

    # DOS calculation.
    dos_strategy = None
    if dos_kppa is not None:
        raise NotImplementedError("DOS must be tested")
        dos_ksampling = KSampling.automatic_density(structure, dos_kppa, chksymbreak=0)
        #dos_ksampling = KSampling.monkhorst(dos_ngkpt, shiftk=dos_shiftk, chksymbreak=0)

        dos_strategy = NscfStrategy(scf_strategy, dos_ksampling, nscf_nband, nscf_solver=None, **extra_abivars)

    return BandStructureWorkflow(scf_strategy, nscf_strategy, dos_inputs=dos_strategy, 
                                 workdir=workdir, manager=manager)
Beispiel #20
0
    def __init__(self, structure, formula, struct_type, pseudos, accuracy, ecut=None, pawecutdg=None, ngkpt=(8, 8, 8),
                 spin_mode="unpolarized", toldfe=1.e-9, smearing="fermi_dirac:0.001 Ha",
                 ecutsm=0.05, chksymbreak=0, workdir=None, manager=None, **kwargs):
        """
        Build a :class:`Work` for the computation of the relaxed lattice parameter.

        Args:   
            structure: :class:`Structure` object 
            structure_type: fcc, bcc 
            pseudos: Pseudopotentials
            ecut: Cutoff energy in Hartree
            ngkpt: MP divisions.
            spin_mode: Spin polarization mode.
            toldfe: Tolerance on the energy (Ha)
            smearing: Smearing technique.
            workdir: String specifing the working directory.
            manager: :class:`TaskManager` responsible for the submission of the tasks.
        """
        super(GbrvCompoundRelaxAndEosWork, self).__init__(workdir=workdir, manager=manager)

        self.pseudos = pseudos
        self.formula = formula
        self.struct_type = struct_type
        self.accuracy = accuracy
        self.set_name("_".join(["gbrv", struct_type, formula, accuracy]))

        # nband must be large enough to accomodate fractional occupancies.
        fband = kwargs.pop("fband", None)

        # FIXME
        #nband = gbrv_nband(self.pseudo)

        # TODO: toldfe for the EOS, tolvrs for the relaxation.
        # Set extra_abivars.
        self.extra_abivars = dict(
            ecut=ecut,
            pawecutdg=pawecutdg,
            toldfe=toldfe,
            #ecutsm=0.5,
            #nband=nband,
            paral_kgb=kwargs.pop("paral_kgb", 0),
        )
                                       
        self.extra_abivars.update(**kwargs)
        self.ecut = ecut
        self.smearing = Smearing.as_smearing(smearing)

        # Kpoint sampling: shiftk depends on struct_type
        #shiftk = {"fcc": [0, 0, 0], "bcc": [0.5, 0.5, 0.5]}.get(struct_type)
        shiftk = [0, 0, 0]
        #ngkpt = (4,4,4)

        self.ksampling = KSampling.monkhorst(ngkpt, chksymbreak=chksymbreak, shiftk=shiftk)
        self.spin_mode = SpinMode.as_spinmode(spin_mode)
        relax_algo = RelaxationMethod.atoms_and_cell()

        inp = abilab.AbinitInput(structure, pseudos)
        inp.add_abiobjects(self.ksampling, relax_algo, self.spin_mode, self.smearing)
        inp.set_vars(self.extra_abivars)

        # Register structure relaxation task.
        self.relax_task = self.register_relax_task(inp)