Beispiel #1
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 #2
0
    def __init__(self, workdir, manager, pseudo, ecut_list_or_slice, atols_mev,
                 toldfe=1.e-8, spin_mode="polarized", 
                 acell=(8, 9, 10), smearing="fermi_dirac:0.1 eV", max_niter=50,):
        """
        Args:
            workdir:
                Working directory.
            pseudo:
                string or Pseudo instance
            ecut_list_or_slice:
                List of cutoff energies or slice object (mainly used for infinite iterations).
            atols_mev:
                List of absolute tolerances in meV (3 entries corresponding to accuracy ["low", "normal", "high"]
            manager:
                `TaskManager` object.
            spin_mode:
                Defined how the electronic spin will be treated.
            acell:
                Lengths of the periodic box in Bohr.
            smearing:
                Smearing instance or string in the form "mode:tsmear". Default: FemiDirac with T=0.1 eV
        """
        self.pseudo = Pseudo.aspseudo(pseudo)

        self.atols_mev = atols_mev
        self.toldfe = toldfe
        self.spin_mode = spin_mode
        self.smearing = Smearing.assmearing(smearing)
        self.acell = acell

        if isinstance(ecut_list_or_slice, slice):
            self.ecut_iterator = iterator_from_slice(ecut_list_or_slice)
        else:
            self.ecut_iterator = iter(ecut_list_or_slice)

        # Construct a generator that returns strategy objects.
        def strategy_generator():
            for ecut in self.ecut_iterator:
                yield self.strategy_with_ecut(ecut)

        super(PseudoIterativeConvergence, self).__init__(strategy_generator(), 
              max_niter=max_niter, workdir=workdir, manager=manager, )

        if not self.isnc:
            raise NotImplementedError("PAW convergence tests are not supported yet")
Beispiel #3
0
    def work_for_pseudo(self, workdir, pseudo, ecut_range, 
                        runmode="sequential", toldfe=1.e-8,
                        atols_mev=(10, 1, 0.1), spin_mode="polarized",
                        acell=(8, 9, 10), smearing="fermi_dirac:0.1 eV",):
        """
        Return a Work object given the pseudopotential pseudo.

        Args:
            workdir:
                Working directory.
            pseudo:
                Pseudo object.
            ecut_range:
                range of cutoff energies in Ha units.
            runmode:
                Run mode.
            toldfe:
                Tolerance on the total energy (Ha).
            atols_mev:
                Tolerances in meV for accuracy in ["low", "normal", "high"]
            spin_mode:
                Spin polarization.
            acell:
                Length of the real space lattice (Bohr units)
            smearing:
                Smearing technique.
        """
        workdir = os.path.abspath(workdir)

        smearing = Smearing.assmearing(smearing)

        if isinstance(ecut_range, slice):
            workflow = PseudoIterativeConvergence(
                workdir, pseudo, ecut_range, atols_mev, 
                runmode=runmode, toldfe=toldfe, spin_mode=spin_mode, 
                acell=acell, smearing=smearing)

        else:
            workflow = PseudoConvergence(
                workdir, pseudo, ecut_range, atols_mev, 
                runmode=runmode, toldfe=toldfe, spin_mode=spin_mode, 
                acell=acell, smearing=smearing)

        return workflow
Beispiel #4
0
    def work_for_pseudo(self, workdir, manager, pseudo, ecut_range, 
                        toldfe=1.e-8, atols_mev=(10, 1, 0.1), spin_mode="polarized",
                        acell=(8, 9, 10), smearing="fermi_dirac:0.1 eV",):
        """
        Return a `Workflow` object given the pseudopotential pseudo.

        Args:
            workdir:
                Working directory.
            pseudo:
                Pseudo object.
            ecut_range:
                range of cutoff energies in Ha units.
            manager:
                `TaskManager` object.
            toldfe:
                Tolerance on the total energy (Ha).
            atols_mev:
                Tolerances in meV for accuracy in ["low", "normal", "high"]
            spin_mode:
                Spin polarization.
            acell:
                Length of the real space lattice (Bohr units)
            smearing:
                Smearing technique.
        """
        workdir = os.path.abspath(workdir)

        smearing = Smearing.assmearing(smearing)

        if isinstance(ecut_range, slice):
            workflow = PseudoIterativeConvergence(
                workdir, manager, pseudo, ecut_range, atols_mev, 
                toldfe=toldfe, spin_mode=spin_mode, 
                acell=acell, smearing=smearing)

        else:
            workflow = PseudoConvergence(
                workdir, manager, pseudo, ecut_range, atols_mev, 
                toldfe=toldfe, spin_mode=spin_mode, 
                acell=acell, smearing=smearing)

        return workflow
Beispiel #5
0
    def __init__(self, pseudo, ecut_slice, nlaunch, atols_mev,
                 toldfe=1.e-8, spin_mode="polarized", acell=(8, 9, 10), 
                 smearing="fermi_dirac:0.1 eV", max_niter=300, workdir=None, manager=None):
        """
        Args:
            pseudo: string or :class:`Pseudo` instance
            ecut_slice: List of cutoff energies or slice object (mainly used for infinite iterations).
            nlaunch:
            atols_mev: List of absolute tolerances in meV (3 entries corresponding to accuracy ["low", "normal", "high"]
            spin_mode: Defined how the electronic spin will be treated.
            acell: Lengths of the periodic box in Bohr.
            smearing: :class:`Smearing` instance or string in the form "mode:tsmear". Default: FemiDirac with T=0.1 eV
            max_niter:
            workdir: Working directory.
            manager: :class:`TaskManager` object.
        """
        super(PseudoConvergence, self).__init__(workdir, manager)

        self._pseudo = Pseudo.as_pseudo(pseudo)
        self.nlaunch = nlaunch; assert nlaunch > 0
        self.atols_mev = atols_mev
        self.toldfe = toldfe
        self.spin_mode = SpinMode.as_spinmode(spin_mode)
        self.acell = acell
        self.smearing = Smearing.as_smearing(smearing)
        self.max_niter = max_niter; assert max_niter > 0
        self.ecut_slice = ecut_slice; assert isinstance(ecut_slice, slice)

        self.ecuts = []

        if self.pseudo.ispaw:
            raise NotImplementedError("PAW convergence tests are not supported yet")

        for i in range(self.nlaunch):
            ecut = ecut_slice.start + i * ecut_slice.step
            #if self.ecut_slice.stop is not None and ecut > self.ecut_slice.stop: continue
            self.add_task_with_ecut(ecut)
Beispiel #6
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 #7
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 #8
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)