Esempio n. 1
0
    def build_structure(self, ref="ae"):
        """
        Returns the crystalline structure associated to this entry.
        Use the optimized lattice parameters obtained from reference ref.
        Returns None if no lattice parameter is available.
        """
        # Get structure type and lattice parameters
        stype, a = self.struct_type, getattr(self, ref)

        # Handle missing value.
        if a is None:
            return None

        if stype == "bcc":
            return Structure.bcc(a, species=[self.symbol])

        elif stype == "fcc":
            return Structure.fcc(a, species=[self.symbol])

        elif stype == "rocksalt":
            return Structure.rocksalt(a, self.species)

        elif stype == "ABO3":
            return Structure.ABO3(a, self.species)

        elif stype == "hH":
            raise NotImplementedError()
            #return Structure.hH(a, sites)

        raise ValueError("Don't know how to construct %s structure" % stype)
Esempio n. 2
0
    def build_structure(self, ref="ae"):
        """
        Returns the crystalline structure associated to this entry.
        Use the optimized lattice parameters obtained from reference ref.
        Returns None if no lattice parameter is available.
        """
        # Get structure type and lattice parameters
        stype, a = self.struct_type, getattr(self, ref)

        # Handle missing value.
        if a is None:
            return None

        if stype == "bcc":
            return Structure.bcc(a, species=[self.symbol])
        elif stype == "fcc":
            return Structure.fcc(a, species=[self.symbol])
        elif stype == "rocksalt":
            return Structure.rocksalt(a, self.species)
        elif stype == "ABO3":
            return Structure.ABO3(a, self.species)
        elif stype == "hH":
            return half_heusler(a, self.species)

        raise ValueError("Don't know how to construct %s structure" % stype)
Esempio n. 3
0
    def __init__(self, a_guess, struct_type, pseudo, ecut_list=None, pawecutdg=None, ngkpt=(8, 8, 8),
                 spin_mode="unpolarized", include_soc=False, tolvrs=1.e-10, smearing="fermi_dirac:0.001 Ha",
                 ecutsm=0.05, chksymbreak=0, workdir=None, manager=None):
        """
        Build a :class:`Work` for the computation of the relaxed lattice parameter.

        Args:
            structure_type: fcc, bcc
            pseudo: :class:`Pseudo` object.
            ecut_list: 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(RelaxWithGbrvParamsWork, self).__init__(workdir=workdir, manager=manager)
        self_pseudo = pseudo
        self.include_soc = include_soc
        self.struct_type = struct_type

        if struct_type == "bcc":
            structure = Structure.bcc(a_guess, species=[pseudo.symbol])
        elif struct_type == "fcc":
            structure = Structure.fcc(a_guess, species=[pseudo.symbol])

        # Set extra_abivars.
        extra_abivars = dict(
            pawecutdg=pawecutdg,
            tolvrs=tolvrs,
            prtwf=-1,
            fband=3.0,
            nstep=100,
            ntime=50,
            ecutsm=ecutsm,
            dilatmx=1.1,
        )

        self.ecut_list = ecut_list
        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)
        spin_mode = SpinMode.as_spinmode(spin_mode)
        ksampling = KSampling.monkhorst(ngkpt, chksymbreak=chksymbreak, shiftk=shiftk,
                                        use_time_reversal=spin_mode.nspinor==1)
        relax_algo = RelaxationMethod.atoms_and_cell()

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

        # Register structure relaxation task.
        for ecut in self.ecut_list:
            self.relax_task = self.register_relax_task(inp.new_with_vars(ecut=ecut))
Esempio n. 4
0
    def read_all_structures(self):
        """Return the list of structures at the different iteration steps."""
        rprimd_list = self.read_value("rprimd")
        xred_list = self.read_value("xred")

        # Alchemical mixing is not supported.
        num_pseudos = self.read_dimvalue("npsp")
        ntypat = self.read_dimvalue("ntypat")
        if num_pseudos != ntypat:
            raise NotImplementedError(
                "Alchemical mixing is not supported, num_pseudos != ntypat")

        znucl, typat = self.read_value("znucl"), self.read_value(
            "typat").astype(int)
        #print(znucl.dtype, typat)
        cart_forces_step = self.read_cart_forces(unit="eV ang^-1")

        structures = []
        #print("typat", type(typat))
        for step in range(self.num_steps):
            s = Structure.from_abivars(
                xred=xred_list[step],
                rprim=rprimd_list[step],
                acell=3 * [1.0],
                # FIXME ntypat, typat, znucl are missing!
                znucl=znucl,
                typat=typat,
            )
            s.add_site_property("cartesian_forces", cart_forces_step[step])
            structures.append(s)

        return structures
Esempio n. 5
0
    def __init__(self, nspinor, nsppol, nspden, datar, structure, iorder="c"):
        """
        Args:
            nspinor: Number of spinorial components.
            nsppol: Number of spins.
            nspden: Number of spin density components.
            datar: [nspden, nx, ny, nz] array with the scalar field in real space.
                See also ``read_denpot``.
            structure: |Structure| object describing the crystalline structure.
            iorder: Order of the array. "c" for C ordering, "f" for Fortran ordering.
        """
        self.nspinor, self.nsppol, self.nspden = nspinor, nsppol, nspden
        # Convert to Abipy Structure.
        self._structure = Structure.as_structure(structure)

        iorder = iorder.lower()
        assert iorder in ["f", "c"]

        if iorder == "f":
            # (z,x,y) --> (x,y,z)
            datar = transpose_last3dims(datar)

        # Init Mesh3D
        mesh_shape = datar.shape[-3:]
        self._mesh = Mesh3D(mesh_shape, structure.lattice.matrix)

        # Make sure we have the correct shape.
        self._datar = np.reshape(datar, (nspden,) + self.mesh.shape)
Esempio n. 6
0
    def read_all_structures(self):
        """Return the list of structures at the different iteration steps."""
        rprimd_list = self.read_value("rprimd")
        xred_list = self.read_value("xred")

        # Alchemical mixing is not supported.
        num_pseudos = self.read_dimvalue("npsp")
        ntypat = self.read_dimvalue("ntypat")
        if num_pseudos != ntypat:
            raise NotImplementedError("Alchemical mixing is not supported, num_pseudos != ntypat")

        znucl, typat = self.read_value("znucl"), self.read_value("typat").astype(int)
        #print(znucl.dtype, typat)
        cart_forces_step = self.read_cart_forces(unit="eV ang^-1")

        structures = []
        #print("typat", type(typat))
        for step in range(self.num_steps):
            s = Structure.from_abivars(
                xred=xred_list[step],
                rprim=rprimd_list[step],
                acell=3 * [1.0],
                # FIXME ntypat, typat, znucl are missing!
                znucl=znucl,
                typat=typat,
            )
            s.add_site_property("cartesian_forces", cart_forces_step[step])
            structures.append(s)

        return structures
Esempio n. 7
0
    def from_gsinp(cls, workdir, gsinp, volumes, ngqpt, manager=None):
        """

        Args:
            workdir:
            gsinp:
            volumes:
            ngqpt:
            manager:
        """
        ngqpt = np.reshape(ngqpt, 3)
        flow = cls(workdir=workdir, manager=manager)

        # Construct len(volumes) works. Each work performs the structure relaxation
        # at fixed volume followed by DFPT calculation with the relaxed structure.
        for vol in volumes:
            # Build GS input file for new structure with rescaled volume.
            new_lattice = gsinp.structure.lattice.scale(vol)
            new_structure = Structure(new_lattice, gsinp.structure.species,
                                      gsinp.structure.frac_coords)
            new_input = gsinp.new_with_structure(new_structure)

            # Register work.
            work = RelaxAndPhononWork.from_gsinp(new_input,
                                                 ngqpt,
                                                 optcell=3,
                                                 ionmov=3)
            flow.register_work(work)

        return flow
Esempio n. 8
0
def ion_ioncell_relax_and_ebands_input(structure, pseudos, 
                                        kppa=None, nband=None,
                                        ecut=None, pawecutdg=None, accuracy="normal", spin_mode="polarized",
                                        smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None):
    """
    Returns a :class:`AbinitInput` for a structural relaxation. The first dataset optmizes the 
    atomic positions at fixed unit cell. The second datasets optimizes both ions and unit cell parameters.

    Args:
        structure: :class:`Structure` object.
        pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object.
        kppa: Defines the sampling used for the Brillouin zone.
        nband: Number of bands included in the SCF run.
        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.
    """
    structure = Structure.as_structure(structure)

    relax_multi = ion_ioncell_relax_input(structure, pseudos, 
                                          kppa=kppa, nband=nband,
                                          ecut=ecut, pawecutdg=pawecutdg, accuracy=accuracy, spin_mode=spin_mode,
                                          smearing=smearing, charge=charge, scf_algorithm=scf_algorithm)

    ebands_multi = ebands_input(structure, pseudos, 
                                kppa=kppa, nscf_nband=None, ndivsm=15, 
                                ecut=ecut, pawecutdg=pawecutdg, scf_nband=None, accuracy=accuracy, spin_mode=spin_mode,
                                smearing=smearing, charge=charge, scf_algorithm=scf_algorithm, dos_kppa=None)

    return relax_multi + ebands_multi
Esempio n. 9
0
def scf_input(structure, pseudos, kppa=None, ecut=None, pawecutdg=None, nband=None, accuracy="normal",
              spin_mode="polarized", smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None,
              shift_mode="Monkhorst-Pack"):
    structure = Structure.as_structure(structure)

    abinit_input = AbinitInput(structure, pseudos)

    # Set the cutoff energies.
    abinit_input.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, abinit_input.pseudos))

    # SCF calculation.
    kppa = _DEFAULTS.get("kppa") if kppa is None else kppa
    shifts = (0.5, 0.5, 0.5) if shift_mode[0].lower() == "m" else (0.0, 0.0, 0.0)
    scf_ksampling = aobj.KSampling.automatic_density(structure, kppa, chksymbreak=0, shifts=shifts)
    scf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm=scf_algorithm,
                                   charge=charge, nband=nband, fband=None)

    if spin_mode=="polarized":
        abinit_input.set_autospinat()

    if scf_electrons.nband is None:
        scf_electrons.nband = _find_scf_nband(structure, abinit_input.pseudos, scf_electrons,abinit_input.get('spinat', None))

    abinit_input.set_vars(scf_ksampling.to_abivars())
    abinit_input.set_vars(scf_electrons.to_abivars())
    abinit_input.set_vars(_stopping_criterion("scf", accuracy))

    return abinit_input
Esempio n. 10
0
    def set_structure(self, structure):
        structure = Structure.as_structure(structure)

        self._structure = structure
        if structure is None: return

        self.set_vars(**structure.to_abivars())
Esempio n. 11
0
 def read_structure(self):
     """
     Overrides the ``read_structure`` method so that we always return
     an instance of AbiPy |Structure| object
     """
     from abipy.core.structure import Structure
     return Structure.from_file(self.path)
Esempio n. 12
0
 def test_alpha_sio2(self):
     """Testing wyckoff positions for alpha-SiO2"""
     asi02 = Structure.from_file(
         os.path.join(abidata.dirpath, "refs", "mp-7000_DDB.bz2"))
     ss = asi02.site_symmetries
     df = ss.get_wyckoff_dataframe(verbose=2)
     df = df[df["element"] == "Si"]
     self.assert_equal(df["xfrac"].values, ["xfrac", "yfrac", "0.0"])
     self.assert_equal(df["yfrac"].values, ["0.0", "yfrac", "yfrac"])
     self.assert_equal(np.array(df["zfrac"].values, dtype=float),
                       [0.833335, 0.5, 0.166665])
     """
              wyckoff  site_symmetry    Txx  Tyy  Tzz    Txy    Txz  Tyz
     0      3a  2 (#3,nsym:2)           Txx  Tyy  Tzz  Tyy/2  Tyz/2  Tyz
     1      3a  2 (#3,nsym:2)           Tyy  Tyy  Tzz    Txy   -Tyz  Tyz
     2      3a  2 (#3,nsym:2)         2*Txy  Tyy  Tzz    Txy  2*Tyz  Tyz
     """
     df = ss.get_tensor_rank2_dataframe(verbose=2)
     ref = ["Txx", "Tyy", "2*Txy"]
     self.assert_equal(df["Txx"].values, ref)
     ref = ["Tyy", "Tyy", "Tyy"]
     self.assert_equal(df["Tyy"].values, ref)
     ref = ["Tzz", "Tzz", "Tzz"]
     self.assert_equal(df["Tzz"].values, ref)
     ref = ["Tyy/2", "Txy", "Txy"]
     self.assert_equal(df["Txy"].values, ref)
     ref = ["Tyz/2", "-Tyz", "2*Tyz"]
     self.assert_equal(df["Txz"].values, ref)
     ref = ["Tyz", "Tyz", "Tyz"]
     self.assert_equal(df["Tyz"].values, ref)
Esempio n. 13
0
def ion_ioncell_relax_input(structure,
                            pseudos,
                            kppa=None,
                            nband=None,
                            ecut=None,
                            pawecutdg=None,
                            accuracy="normal",
                            spin_mode="polarized",
                            smearing="fermi_dirac:0.1 eV",
                            charge=0.0,
                            scf_algorithm=None):
    """
    Returns a :class:`AbinitInput` for a structural relaxation. The first dataset optmizes the 
    atomic positions at fixed unit cell. The second datasets optimizes both ions and unit cell parameters.

    Args:
        structure: :class:`Structure` object.
        pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object.
        kppa: Defines the sampling used for the Brillouin zone.
        nband: Number of bands included in the SCF run.
        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.
    """
    structure = Structure.as_structure(structure)
    multi = MultiDataset(structure, pseudos, ndtset=2)

    # Set the cutoff energies.
    multi.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, multi.pseudos))

    kppa = _DEFAULTS.get("kppa") if kppa is None else kppa
    ksampling = aobj.KSampling.automatic_density(structure,
                                                 kppa,
                                                 chksymbreak=0)
    electrons = aobj.Electrons(spin_mode=spin_mode,
                               smearing=smearing,
                               algorithm=scf_algorithm,
                               charge=charge,
                               nband=nband,
                               fband=None)

    if electrons.nband is None:
        electrons.nband = _find_scf_nband(structure, multi.pseudos, electrons)

    ion_relax = aobj.RelaxationMethod.atoms_only(atoms_constraints=None)
    ioncell_relax = aobj.RelaxationMethod.atoms_and_cell(
        atoms_constraints=None)

    multi.set_vars(electrons.to_abivars())
    multi.set_vars(ksampling.to_abivars())

    multi[0].set_vars(ion_relax.to_abivars())
    multi[0].set_vars(_stopping_criterion("relax", accuracy))

    multi[1].set_vars(ioncell_relax.to_abivars())
    multi[1].set_vars(_stopping_criterion("relax", accuracy))

    return multi
Esempio n. 14
0
File: input.py Progetto: kidaa/abipy
    def set_structure(self, structure):
        structure = Structure.as_structure(structure)

        self._structure = structure
        if structure is None: return

        self.set_vars(**structure.to_abivars())
Esempio n. 15
0
    def add_eos_tasks(self):
        """
        Read the optimized structure from the netcdf file and add to self a new
        a new list of ScfTask for the computation of the EOS with the GBRV parameters.
        """
        self.history.info("Building EOS tasks")

        # Get the relaxed structure.
        self.relaxed_structure = relaxed_structure = self.relax_task.get_final_structure()

        # GBRV use nine points from -1% to 1% of the initial guess and fitting the results to a parabola.
        # Note that it's not clear to me if they change the volume or the lattice parameter!
        self.volumes = relaxed_structure.volume * np.arange(99, 101.25, 0.25) / 100.

        for vol in self.volumes:
            new_lattice = relaxed_structure.lattice.scale(vol)
            new_structure = Structure(new_lattice, relaxed_structure.species, relaxed_structure.frac_coords)

            # Add ecutsm
            extra = self.extra_abivars.copy()
            extra["ecutsm"] = 0.5

            scf_input = abilab.AbinitInput(new_structure, self.dojo_pseudo)
            scf_input.add_abiobjects(self.ksampling, self.spin_mode, self.smearing)
            scf_input.set_vars(extra)

            # Register new task
            self.register_scf_task(scf_input)

        # Allocate new tasks and update the pickle database.
        self.flow.allocate()
        self.flow.build_and_pickle_dump()
Esempio n. 16
0
def abifile_subclass_from_filename(filename):
    from abipy.iotools.files import AbinitFile, AbinitLogFile, AbinitOutputFile
    from abipy.electrons import SIGRES_File, GSR_File, MDF_File
    from abipy.waves import WFK_File
    #from abipy.phonons import PHDOS_File, PHBST_File

    ext2ncfile = {
        "SIGRES.nc": SIGRES_File,
        "WFK-etsf.nc": WFK_File,
        "MDF.nc" : MDF_File,
        "GSR.nc": GSR_File
        #"PHDOS.nc": PHDOS_File,
        #"PHBST.nc": PHBST_File,
    }

    #if filename.endswith(".abi"):
    #    return AbinitInputFile
                                                                                        
    if filename.endswith(".abo"):
        return AbinitOutputFile
    
    if filename.endswith(".log"):
        return AbinitLogFile

    # CIF files.
    if filename.endswith(".cif"):
        from abipy.core.structure import Structure
        return Structure.from_file(filename)

    ext = filename.split("_")[-1]
    try:
        return ext2ncfile[ext]
    except KeyError:
        raise KeyError("No class has been registered for extension %s" % ext)
Esempio n. 17
0
    def structure(self):
        kwargs = {}
        if "angdeg" in self:
            assert "rprim" not in self
            raise NotImplementedError("angdeg")
            #kwargs["angdeg"] =
        else:
            # Handle structure specified with rprim.
            kwargs["rprim"] = str2array_bohr(self.get("rprim", "1.0 0 0 0 1 0 0 0 1"))

        # Default value for acell
        acell = str2array_bohr(self.get("acell", "1.0 1.0 1.0"))

        check = {k: 1 for k in ("xred", "xcart", "xangst") if k in self}
        if len(check) != 1:
            raise ValueError("Atomic positions are not specified correctly:\n%s" % str(check))

        if "xred" in self:
            kwargs["xred"] = np.fromstring(self["xred"], sep=" ")
        elif "xcart" in self:
            kwargs["xcart"] = str2array_bohr(self["xcart"])
        elif "xangst" in self:
            kwargs["xangst"] = np.fromstring(self["xangst"], sep=" ")

        return Structure.from_abivars(
            acell=acell,
            znucl=str2array(self["znucl"]),
            typat=str2array(self["typat"]),
            **kwargs
        )
Esempio n. 18
0
 def structure(self):
     structure = Structure.from_abivars(**self.header)
     # Add Spacegroup (needed in guessed_ngkpt)
     # FIXME: has_timerev is always True
     spgid, has_timerev, h = 0, True, self.header
     structure.set_spacegroup(SpaceGroup(spgid, h.symrel, h.tnons, h.symafm, has_timerev))
     return structure
Esempio n. 19
0
    def work_for_pseudo(self, pseudo, accuracy="normal", kppa=6750, ecut=None, pawecutdg=None,
                        toldfe=1.e-9, smearing="fermi_dirac:0.1 eV", workdir=None, manager=None, **kwargs):
        """
        Returns a :class:`Work` object from the given pseudopotential.

        Args:
            kwargs: Extra variables passed to Abinit.

        .. note::

            0.001 Rydberg is the value used with WIEN2K
        """
        pseudo = Pseudo.as_pseudo(pseudo)
        symbol = pseudo.symbol

        if pseudo.ispaw and pawecutdg is None:
            raise ValueError("pawecutdg must be specified for PAW calculations.")

        try:
            cif_path = self.get_cif_path(symbol)
        except Exception as exc:
            raise self.Error(str(exc))

        # Include spin polarization for O, Cr and Mn (antiferromagnetic)
        # and Fe, Co, and Ni (ferromagnetic).
        # antiferromagnetic Cr, O
        # ferrimagnetic Mn
        spin_mode = "unpolarized"

        if symbol in ["Fe", "Co", "Ni"]:
            spin_mode = "polarized"
            if symbol == "Fe":
                kwargs['spinat'] = 2 * [(0, 0, 2.3)]
            if symbol == "Co":
                kwargs['spinat'] = 2 * [(0, 0, 1.2)]
            if symbol == "Ni":
                kwargs['spinat'] = 4 * [(0, 0, 0.6)]

        if symbol in ["O", "Cr", "Mn"]:
            spin_mode = "afm"
            if symbol == 'O':
                kwargs['spinat'] = [(0, 0, 1.5), (0, 0, 1.5), (0, 0, -1.5), (0, 0, -1.5)]
            elif symbol == 'Cr':
                kwargs['spinat'] = [(0, 0, 1.5), (0, 0, -1.5)]
            elif symbol == 'Mn':
                kwargs['spinat'] = [(0, 0, 2.0), (0, 0, 1.9), (0, 0, -2.0), (0, 0, -1.9)]

        # DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE.
        structure = Structure.from_file(cif_path, primitive=False)

        # Magnetic elements:
        # Start from previous SCF run to avoid getting trapped in local minima 
        connect = symbol in ("Fe", "Co", "Ni", "Cr", "Mn", "O", "Zn", "Cu")

        return DeltaFactorWork(
            structure, pseudo, kppa, connect,
            spin_mode=spin_mode, toldfe=toldfe, smearing=smearing,
            accuracy=accuracy, ecut=ecut, pawecutdg=pawecutdg, ecutsm=0.5,
            workdir=workdir, manager=manager, **kwargs)
Esempio n. 20
0
    def structure(self):
        # Get lattice.
        kwargs = {}
        if "angdeg" in self:
            if "rprim" in self:
                raise ValueError("rprim and angdeg cannot be used together!")
            angdeg = str2array(self["angdeg"])
            angdeg.shape = (3)
            kwargs["angdeg"] = angdeg
        else:
            # Handle structure specified with rprim.
            kwargs["rprim"] = str2array_bohr(self.get("rprim", "1.0 0 0 0 1 0 0 0 1"))

        # Default value for acell.
        acell = str2array_bohr(self.get("acell", "1.0 1.0 1.0"))

        # Get important dimensions.
        ntypat = int(self.get("ntypat", 1))
        natom = int(self.get("natom", 1))

        # znucl(npsp)
        znucl = self["znucl"]
        if znucl.startswith("*"):
            i = znucl.find("*")
            znucl_size = natom if "npsp" not in self else int(self["npsp"])
            znucl = znucl_size * [float(znucl[i+1:])]
        else:
            znucl = str2array(self["znucl"])

        # v67mbpt/Input/t12.in
        typat = self["typat"]
        if typat.startswith("*"):
            i = typat.find("*")
            typat = np.array(natom * [int(typat[i+1:])], dtype=int)
        else:
            typat = str2array(self["typat"], dtype=int)

        # Extract atomic positions.
        # Select first natom entries (needed if multidatasets with different natom)
        #    # v3/Input/t05.in
        typat = typat[:natom]
        for k in ("xred", "xcart", "xangst"):
            toarray = str2array_bohr if k == "xcart" else str2array
            if k in self:
                arr = np.reshape(toarray(self[k]), (-1, 3))
                kwargs[k] = arr[:natom]
                break
        else:
            raise ValueError("xred|xcart|xangst must be given in input")

        try:
            return Structure.from_abivars(acell=acell, znucl=znucl, typat=typat, **kwargs)
        except Exception as exc:
            print("Wrong inputs passed to Structure.from_abivars:")
            print("  acell", acell)
            print("  znucl", znucl)
            print("  typat", typat)
            print("  kwargs", kwargs)
            raise exc
Esempio n. 21
0
 def structure(self):
     coords = []
     coords.append([0, 0, 0])
     coords.append([0.75, 0.5, 0.75])
     lattice = Lattice([[3.8401979337, 0.00, 0.00],
                        [1.9200989668, 3.3257101909, 0.00],
                        [0.00, -2.2171384943, 3.1355090603]])
     return Structure(lattice, ["Si", "Si"], coords)
Esempio n. 22
0
    def set_structure(self, structure, dtset=0):
        """Set the :class:`Structure` object for the specified dtset."""
        structure = Structure.as_structure(structure)

        if dtset is None:
            dtset = slice(self.ndtset + 1)
        for idt in self._dtset2range(dtset):
            self[idt].set_structure(structure)
Esempio n. 23
0
File: input.py Progetto: kidaa/abipy
    def set_structure(self, structure, dtset=0):
        """Set the :class:`Structure` object for the specified dtset."""
        structure = Structure.as_structure(structure)

        if dtset is None:
            dtset = slice(self.ndtset+1)
        for idt in self._dtset2range(dtset):
            self[idt].set_structure(structure)
Esempio n. 24
0
    def work_for_pseudo(self,
                        pseudo,
                        kppa=3000,
                        maxene=250,
                        ecut=None,
                        pawecutdg=None,
                        spin_mode="unpolarized",
                        include_soc=False,
                        tolwfr=1.e-12,
                        smearing="fermi_dirac:0.1 eV",
                        workdir=None,
                        manager=None,
                        **kwargs):
        """
        Returns a :class:`Work` object from the given pseudopotential.

        Args:
            pseudo: :class:`Pseudo` object.
            kppa: Number of k-points per reciprocal atom.
            ecut: Cutoff energy in Hartree
            pawecutdg: Cutoff energy of the fine grid (PAW only)
            spin_mode: Spin polarization option
            tolwfr: Tolerance on the residuals.
            smearing: Smearing technique.
            workdir: Working directory.
            manager: :class:`TaskManager` object.
            kwargs: Extra variables passed to Abinit.
        """
        if pseudo.ispaw and pawecutdg is None:
            raise ValueError(
                "pawecutdg must be specified for PAW calculations.")

        if pseudo.xc != self._dfdb.xc:
            raise ValueError(
                "Pseudo xc differs from the XC used to instantiate the factory\n"
                "Pseudo: %s, Database: %s" % (pseudo.xc, self._dfdb.xc))
        try:
            cif_path = self.get_cif_path(pseudo.symbol)
        except Exception as exc:
            raise self.Error(str(exc))

        # DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE.
        structure = Structure.from_file(cif_path, primitive=False)

        return GhostsWork(structure,
                          pseudo,
                          kppa,
                          maxene,
                          spin_mode=spin_mode,
                          include_soc=include_soc,
                          tolwfr=tolwfr,
                          smearing=smearing,
                          ecut=ecut,
                          pawecutdg=pawecutdg,
                          ecutsm=0.5,
                          workdir=workdir,
                          manager=manager,
                          **kwargs)
Esempio n. 25
0
    def from_gs_input(cls,
                      gsinp,
                      voldelta,
                      scdims,
                      phonopy_kwargs=None,
                      displ_kwargs=None):
        """
        Build the work from an :class:`AbinitInput` object representing a GS calculations.

	Args:
	    gsinp:
		:class:`AbinitInput` object representing a GS calculation in the initial unit cell.
	    voldelta:
                Absolute increment for unit cell volume. The three volumes are:
                     [v0 - voldelta, v0, v0 + voldelta] where v0 is taken from gsinp.structure.
	    scdims:
		Number of unit cell replicas along the three reduced directions.
	    phonopy_kwargs:
		(Optional) dictionary with arguments passed to Phonopy constructor.
	    displ_kwargs:
		(Optional) dictionary with arguments passed to generate_displacements.

	Return:
	    `PhonopyGruneisenWork` instance.
        """
        new = cls()

        # Save arguments that will be used to call phonopy for creating
        # the supercells with the displacements once the three volumes have been relaxed.
        new.scdims = np.array(scdims)
        if new.scdims.shape != (3, ):
            raise ValueError("Expecting 3 int in scdims but got %s" %
                             str(new.scdims))
        new.phonopy_kwargs = phonopy_kwargs if phonopy_kwargs is not None else {}
        new.displ_kwargs = displ_kwargs if displ_kwargs is not None else {}

        # Build three tasks for structural optimization at constant volume.
        v0 = gsinp.structure.volume
        if voldelta <= 0:
            raise ValueError("voldelta must be > 0 but got %s" % voldelta)
        volumes = [v0 - voldelta, v0, v0 + voldelta]
        if any(v <= 0 for v in volumes):
            raise ValueError("volumes must be > 0 but got %s" % str(volumes))

        for vol in volumes:
            # Build new structure
            new_lattice = gsinp.structure.lattice.scale(vol)
            new_structure = Structure(new_lattice, gsinp.structure.species,
                                      gsinp.structure.frac_coords)
            new_input = gsinp.new_with_structure(new_structure)
            # Set variables for structural optimization at constant volume.
            new_input.pop_tolerances()
            new_input.set_vars(optcell=3, ionmov=3, tolvrs=1e-10, toldff=1.e-6)
            new_input.set_vars_ifnotin(ecutsm=0.5, dilatmx=1.05)
            new.register_relax_task(new_input)

        return new
Esempio n. 26
0
def structure_from_atoms(atoms):
    """
    Convert a phonopy Atoms object into a pymatgen Structure.
    """
    return Structure(lattice=atoms.cell,
                     species=atoms.symbols,
                     coords=atoms.scaled_positions,
                     validate_proximity=False, to_unit_cell=False,
                     coords_are_cartesian=False, site_properties=None)
Esempio n. 27
0
    def work_for_pseudo(self, pseudo, kppa=6750, ecut=None, pawecutdg=None,
                        toldfe=1.e-9, smearing="fermi_dirac:0.1 eV", include_soc=False,
                        workdir=None, manager=None, **kwargs):
        """
        Returns a :class:`Work` object from the given pseudopotential.

        Args:
            pseudo: :class:`Pseudo` object.
            kppa: kpoint per reciprocal atom
            ecut: Cutoff energy in Hartree
            pawecutdg: Cutoff energy of the fine grid (PAW only)
            toldfe: Tolerance on the energy (Ha)
            smearing: Smearing technique.
            include_soc: True if pseudo has SO contributions and calculation should be done with nspinor=2
            workdir: String specifing the working directory.
            manager: :class:`TaskManager` responsible for the submission of the tasks.
            kwargs: Extra variables passed to Abinit.

        .. note::

            0.001 Rydberg is the value used with WIEN2K
        """
        symbol = pseudo.symbol
        if pseudo.ispaw and pawecutdg is None:
            raise ValueError("pawecutdg must be specified for PAW calculations.")

        if pseudo.xc != self._dfdb.xc:
            raise ValueError(
                "Pseudo xc differs from the XC used to instantiate the factory\n"
                "Pseudo: %s, Database: %s" % (pseudo.xc, self._dfdb.xc))

        try:
            cif_path = self.get_cif_path(symbol)
        except Exception as exc:
            raise self.Error(str(exc))

        # WARNING: DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE.
        structure = Structure.from_file(cif_path, primitive=False)

        # Include spin polarization and initial spinat for particular elements
        # TODO: Not sure spinat is ok if LDA.
        kwargs["spinat"], spin_mode = self._dfdb.spinat_spinmode_for_symbol(symbol)
        if include_soc: spin_mode = "spinor"
        # This is needed for LDA
        if symbol in ("O", "Mn"):
            print("Got Oxygen or Mn")
            spin_mode = "polarized"

        # Magnetic elements:
        # Start from previous SCF run to avoid getting trapped in local minima
        connect = symbol in ("Fe", "Co", "Ni", "Cr", "Mn", "O", "Zn", "Cu")

        return DeltaFactorWork(
            structure, pseudo, kppa, connect,
            spin_mode=spin_mode, include_soc=include_soc, toldfe=toldfe, smearing=smearing,
            ecut=ecut, pawecutdg=pawecutdg, ecutsm=0.5,
            workdir=workdir, manager=manager, **kwargs)
Esempio n. 28
0
def ion_ioncell_relax_and_ebands_input(structure,
                                       pseudos,
                                       kppa=None,
                                       nband=None,
                                       ecut=None,
                                       pawecutdg=None,
                                       accuracy="normal",
                                       spin_mode="polarized",
                                       smearing="fermi_dirac:0.1 eV",
                                       charge=0.0,
                                       scf_algorithm=None):
    """
    Returns a :class:`AbinitInput` for a structural relaxation. The first dataset optmizes the 
    atomic positions at fixed unit cell. The second datasets optimizes both ions and unit cell parameters.

    Args:
        structure: :class:`Structure` object.
        pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object.
        kppa: Defines the sampling used for the Brillouin zone.
        nband: Number of bands included in the SCF run.
        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.
    """
    structure = Structure.as_structure(structure)

    relax_multi = ion_ioncell_relax_input(structure,
                                          pseudos,
                                          kppa=kppa,
                                          nband=nband,
                                          ecut=ecut,
                                          pawecutdg=pawecutdg,
                                          accuracy=accuracy,
                                          spin_mode=spin_mode,
                                          smearing=smearing,
                                          charge=charge,
                                          scf_algorithm=scf_algorithm)

    ebands_multi = ebands_input(structure,
                                pseudos,
                                kppa=kppa,
                                nscf_nband=None,
                                ndivsm=15,
                                ecut=ecut,
                                pawecutdg=pawecutdg,
                                scf_nband=None,
                                accuracy=accuracy,
                                spin_mode=spin_mode,
                                smearing=smearing,
                                charge=charge,
                                scf_algorithm=scf_algorithm,
                                dos_kppa=None)

    return relax_multi + ebands_multi
Esempio n. 29
0
    def structure(self):
        # Get lattice.
        kwargs = {}
        if "angdeg" in self:
            if "rprim" in self:
                raise ValueError("rprim and angdeg cannot be used together!")
            angdeg = str2array(self["angdeg"])
            angdeg.shape = (3)
            kwargs["angdeg"] = angdeg
        else:
            # Handle structure specified with rprim.
            kwargs["rprim"] = str2array_bohr(self.get("rprim", "1.0 0 0 0 1 0 0 0 1"))

        # Default value for acell.
        acell = str2array_bohr(self.get("acell", "1.0 1.0 1.0"))

        # Get important dimensions.
        ntypat = int(self.get("ntypat", 1))
        natom = int(self.get("natom", 1))

        # znucl(npsp)
        znucl = self["znucl"]
        if znucl.startswith("*"):
            i = znucl.find("*")
            znucl_size = natom if "npsp" not in self else int(self["npsp"])
            znucl = znucl_size * [float(znucl[i+1:])]
        else:
            znucl = str2array(self["znucl"])

        # v67mbpt/Input/t12.in
        typat = self["typat"]
        if typat.startswith("*"):
            i = typat.find("*")
            typat = np.array(natom * [int(typat[i+1:])], dtype=int)
        else:
            typat = str2array(self["typat"], dtype=int)

        # Extract atomic positions.
        # Select first natom entries (needed if multidatasets with different natom)
        #    # v3/Input/t05.in
        typat = typat[:natom]
        for k in ("xred", "xcart", "xangst"):
            toarray = str2array_bohr if k == "xcart" else str2array
            if k in self:
                arr = np.reshape(toarray(self[k]), (-1, 3))
                kwargs[k] = arr[:natom]
                break
        else:
            raise ValueError("xred|xcart|xangst must be given in input")

        try:
            return Structure.from_abivars(acell=acell, znucl=znucl, typat=typat, **kwargs)
        except Exception as exc:
            print("Wrong inputs passed to Structure.from_abivars:")
            print("acell:", acell, "znucl:", znucl, "typat:", typat, "kwargs:", kwargs, sep="\n")
            raise exc
Esempio n. 30
0
    def work_for_pseudo(self, pseudo, **kwargs):
        """
        Create a :class:`Flow` for phonon calculations:

            1) One workflow for the GS run.

            2) nqpt workflows for phonon calculations. Each workflow contains
               nirred tasks where nirred is the number of irreducible phonon perturbations
               for that particular q-point.

            the kwargs are passed to scf_hp_inputs
        """
        try:
            qpt = kwargs['qpt']
        except IndexError:
            raise ValueError('A phonon test needs to specify a qpoint.')

        kwargs.pop('accuracy')

        pseudo = Pseudo.as_pseudo(pseudo)

        structure_or_cif = self.get_cif_path(pseudo.symbol)

        if not isinstance(structure_or_cif, Structure):
            # Assume CIF file
            structure = Structure.from_file(structure_or_cif, primitive=False)
        else:
            structure = structure_or_cif

        nat = len(structure)
        report = pseudo.read_dojo_report()
        ecut_str = '%.1f' % kwargs['ecut']
        #print(ecut_str)
        #print(report['deltafactor'][float(ecut_str)].keys())

        try:
            v0 = nat * report['deltafactor'][ecut_str]['v0']
        except KeyError:
            try:
                v0 = nat * report['deltafactor'][float(ecut_str)]['v0']
            except KeyError:
                # the df calculation at this ecut is not done already so the phonon task can not be created
                return None

        structure.scale_lattice(v0)
        all_inps = self.scf_ph_inputs(pseudos=[pseudo], structure=structure, **kwargs)
        scf_input, ph_inputs = all_inps[0], all_inps[1:]

        work = build_oneshot_phononwork(scf_input=scf_input, ph_inputs=ph_inputs, work_class=PhononDojoWork)
        #print('after build_oneshot_phonon')
        #print(work)
        work.set_dojo_trial(qpt)
        #print(scf_input.keys())
        work.ecut = scf_input['ecut']
        work._pseudo = pseudo
        return work
Esempio n. 31
0
    def from_scf_input(cls, scf_input, npoints=4, deltap_vol=0.25, ecutsm=0.5, move_atoms=True,
                       manager=None):
        """
        Build a EosWork from an AbinitInput representing a SCF-GS calculation.

        Args:
            scf_input: AbinitInput for SCF-GS used as template to generate the other inputs.
            npoints: Number of volumes generated on the right (left) of the equilibrium volume
                The total number of points is therefore 2 * n + 1.
            deltap_vol: Step of the linear mesh given in relative percentage of the equilibrium volume
                The step is thus: v0 * deltap_vol / 100.
            ecutsm: Value of ecutsm input variable. If `scf_input` does not provide ecutsm, this
                value will be used else the vale in `scf_input`.
            move_atoms: If True, a structural relaxation of ions is performed for each volume
                This is needed if the atomic positions are non fixed by symmetry.
            manager: TaskManager instance. Use default if None.

        Return: EosWork instance.
        """
        new_work = cls(manager=manager)

        structure = scf_input.structure
        lattice_type = structure.spget_lattice_type()
        assert lattice_type is not None

        dvol = structure.volume * deltap_vol / 100
        v0 = structure.volume - dvol * npoints
        new_work.input_volumes = [v0 + ipt * dvol for ipt in range(2 * npoints + 1)]

        if "ecutsm" not in scf_input:
            print("Input does not define ecutsm input variable.\n",
                  "A default value of %s will be added to all the EOS inputs" % ecutsm)

        for vol in new_work.input_volumes:
            # Build structure with new volume and generate new input.
            new_lattice = structure.lattice.scale(vol)
            new_structure = Structure(new_lattice, structure.species, structure.frac_coords)
            new_input = scf_input.new_with_structure(new_structure)

            # Add ecutsm if not already present.
            new_input.set_vars_ifnotin(ecutsm=ecutsm)

            if lattice_type == "cubic" and not move_atoms:
                # Perform GS calculations without moving atoms, cells do not need to be relaxed.
                new_input.pop_vars(["ionmov", "optcell", "ntime"])
                new_work.register_scf_task(new_input)
            else:
                # Constant-volume optimization of cell geometry + atoms.
                # (modify acell and rprim under constraint - normalize the vectors of rprim to generate the acell)
                # In principle one could take into account the symmetry of the lattice...
                new_input.set_vars_ifnotin(ionmov=2, ntime=50, optcell=3, dilatmx=1.05)
                new_work.register_relax_task(new_input)

        return new_work
Esempio n. 32
0
    def __init__(self, entries):
        self.entries = entries
        from abipy.core.structure import Structure
        for e in entries:
            e.structure = Structure.as_structure(e.structure)

        self.structures = [e.structure for e in entries]
        self.mpids = [e.entry_id for e in entries]

        # Create phase diagram.
        from pymatgen.analysis.phase_diagram import PhaseDiagram
        self.phasediagram = PhaseDiagram(self.entries)
Esempio n. 33
0
    def _generate_inputdata(self,
                            parameters: orm.Dict,
                            pseudos,
                            structure: orm.StructureData,
                            kpoints: orm.KpointsData) -> ty.Tuple[str, list]:
        """Generate the input file content and list of pseudopotential files to copy.

        :param parameters: input parameters Dict
        :param pseudos: pseudopotential input namespace
        :param structure: input structure
        :param kpoints: input kpoints
        :returns: input file content, pseudopotential copy list
        """
        local_copy_pseudo_list = []

        # abipy has its own subclass of Pymatgen's `Structure`, so we use that
        pmg_structure = structure.get_pymatgen()
        abi_structure = AbiStructure.as_structure(pmg_structure)
        abi_structure = abi_structure.abi_sanitize(primitive=True)

        for kind in structure.get_kind_names():
            pseudo = pseudos[kind]
            local_copy_pseudo_list.append((pseudo.uuid, pseudo.filename, f'{self._PSEUDO_SUBFOLDER}{pseudo.filename}'))
        # Pseudopotentials _must_ be listed in the same order as 'znucl' in the input file.
        # So, we need to get 'znucl' as abipy will write it then construct the appropriate 'pseudos' string.
        znucl = structure_to_abivars(abi_structure)['znucl']
        ordered_pseudo_filenames = [pseudos[constants.elements[Z]['symbol']].filename for Z in znucl]
        pseudo_parameters = {
            'pseudos': '"' + ', '.join(ordered_pseudo_filenames) + '"',
            'pp_dirpath': f'"{self._PSEUDO_SUBFOLDER}"'
        }

        input_parameters = parameters.get_dict()
        # k-points are provided to abipy separately from the main input parameters, so we pop out
        # parameters related to the k-points
        shiftk = input_parameters.pop('shiftk', [0.0, 0.0, 0.0])
        # NOTE: currently, only k-point mesh are supported, not k-point paths
        kpoints_mesh = kpoints.get_kpoints_mesh()[0]

        # use abipy to write the input file
        input_parameters = {**input_parameters, **pseudo_parameters}
        # give abipy the HGH_TABLE only so it won't error, but don't actually print these to file
        abi_input = AbinitInput(
            structure=abi_structure,
            pseudos=HGH_TABLE,
            abi_kwargs=input_parameters
        )
        abi_input.set_kmesh(
            ngkpt=kpoints_mesh,
            shiftk=shiftk
        )

        return abi_input.to_string(with_pseudos=False), local_copy_pseudo_list
Esempio n. 34
0
    def __init__(self, entries):
        self.entries = entries
        from abipy.core.structure import Structure
        for e in entries:
            e.structure = Structure.as_structure(e.structure)

        self.structures = [e.structure for e in entries]
        self.mpids = [e.entry_id for e in entries]

        # Create phase diagram.
        from pymatgen.analysis.phase_diagram import PhaseDiagram
        self.phasediagram = PhaseDiagram(self.entries)
Esempio n. 35
0
    def from_gs_input(cls, gs_inp, voldelta, ngqpt, tolerance=None, with_becs=False,
                      ddk_tolerance=None, workdir=None, manager=None):
        """
        Build the work from an |AbinitInput| representing a GS calculations.

        Args:
            gs_inp: |AbinitInput| representing a GS calculation in the initial unit cell.
            voldelta: Absolute increment for unit cell volume. The three volumes are:
                [v0 - voldelta, v0, v0 + voldelta] where v0 is taken from gs_inp.structure.
            ngqpt: three integers defining the q-mesh for phonon calculations.
            tolerance: dict {"varname": value} with the tolerance to be used in the phonon run.
                None to use AbiPy default.
            with_becs: Activate calculation of Electric field and Born effective charges.
            ddk_tolerance: dict {"varname": value} with the tolerance used in the DDK run if with_becs.
                None to use AbiPy default.
        """
        new = cls(workdir=workdir, manager=manager)
        new.ngqpt = np.reshape(ngqpt, (3,))
        new.with_becs = with_becs
        new.ddk_tolerance = ddk_tolerance
        new.tolerance = tolerance

        if any(gs_inp["ngkpt"] % new.ngqpt != 0):
            raise ValueError("Kmesh and Qmesh must be commensurate.\nGot ngkpt: `%s`\nand ngqpt: `%s`" % (
                             str(gs_inp["ngkpt"]), str(new.ngqpt)))

        # Build three tasks for structural optimization at constant volume.
        v0 = gs_inp.structure.volume
        if voldelta <= 0:
            raise ValueError("voldelta must be > 0 but got %s" % voldelta)
        volumes = [v0 - voldelta, v0, v0 + voldelta]
        if any(v <= 0 for v in volumes):
            raise ValueError("volumes must be > 0 but got %s" % str(volumes))

        # Keep a copy of the GS input that will be used to generate the Phonon Works
        new.gs_inp = gs_inp.deepcopy()

        new.relax_tasks = []
        for vol in volumes:
            # Build new structure
            new_lattice = gs_inp.structure.lattice.scale(vol)
            new_structure = Structure(new_lattice, gs_inp.structure.species, gs_inp.structure.frac_coords)
            new_input = gs_inp.new_with_structure(new_structure)
            # Set variables for structural optimization at constant volume.
            new_input.pop_tolerances()
            new_input.set_vars(optcell=3, ionmov=3, tolvrs=1e-10, toldff=1.e-6)
            new_input.set_vars_ifnotin(ecutsm=0.5, dilatmx=1.05)
            t = new.register_relax_task(new_input)
            new.relax_tasks.append(t)

        return new
Esempio n. 36
0
def ion_ioncell_relax_input(structure, pseudos, 
                            kppa=None, nband=None,
                            ecut=None, pawecutdg=None, accuracy="normal", spin_mode="polarized",
                            smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None):
    """
    Returns a :class:`AbinitInput` for a structural relaxation. The first dataset optmizes the 
    atomic positions at fixed unit cell. The second datasets optimizes both ions and unit cell parameters.

    Args:
        structure: :class:`Structure` object.
        pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object.
        kppa: Defines the sampling used for the Brillouin zone.
        nband: Number of bands included in the SCF run.
        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.
    """
    structure = Structure.as_structure(structure)
    multi = MultiDataset(structure, pseudos, ndtset=2)

    # Set the cutoff energies.
    multi.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, multi.pseudos))

    kppa = _DEFAULTS.get("kppa") if kppa is None else kppa
    ksampling = aobj.KSampling.automatic_density(structure, kppa, chksymbreak=0)
    electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm=scf_algorithm, 
                               charge=charge, nband=nband, fband=None)

    if spin_mode=="polarized":
        spinat_dict = multi[0].set_autospinat()
        multi[1].set_vars(spinat_dict)

    if electrons.nband is None:
        electrons.nband = _find_scf_nband(structure, multi.pseudos, electrons, multi[0].get('spinat', None))

    ion_relax = aobj.RelaxationMethod.atoms_only(atoms_constraints=None)
    ioncell_relax = aobj.RelaxationMethod.atoms_and_cell(atoms_constraints=None)

    multi.set_vars(electrons.to_abivars())
    multi.set_vars(ksampling.to_abivars())

    multi[0].set_vars(ion_relax.to_abivars())
    multi[0].set_vars(_stopping_criterion("relax", accuracy))

    multi[1].set_vars(ioncell_relax.to_abivars())
    multi[1].set_vars(_stopping_criterion("relax", accuracy))

    return multi
Esempio n. 37
0
def cube_read_structure_mesh_data(file):
    with open(file, 'r') as fh:
        # The two first lines are comments
        for ii in range(2):
            fh.readline()
        # Number of atoms
        natoms = int(fh.readline().split()[0])
        # The next three lines give the mesh and the vectors
        sp = fh.readline().split()
        nx = int(sp[0])
        dvx = np.array([float(sp[ii])
                        for ii in range(1, 4)]) * bohr_to_angstrom
        sp = fh.readline().split()
        ny = int(sp[0])
        dvy = np.array([float(sp[ii])
                        for ii in range(1, 4)]) * bohr_to_angstrom
        sp = fh.readline().split()
        nz = int(sp[0])
        dvz = np.array([float(sp[ii])
                        for ii in range(1, 4)]) * bohr_to_angstrom
        uc_matrix = np.array([nx * dvx, ny * dvy, nz * dvz])
        sites = []
        lattice = Lattice(uc_matrix)
        for ii in range(natoms):
            sp = fh.readline().split()
            cc = np.array([float(sp[ii])
                           for ii in range(2, 5)]) * bohr_to_angstrom
            sites.append(
                PeriodicSite(int(sp[0]),
                             coords=cc,
                             lattice=lattice,
                             to_unit_cell=False,
                             coords_are_cartesian=True))
        data = np.zeros((nx, ny, nz))
        ii = 0
        for line in fh:
            for val in line.split():
                data[ii // (ny * nz), (ii // nz) % ny, ii % nz] = float(val)
                ii += 1
        data = data / (bohr_to_angstrom**3)
        if ii != nx * ny * nz:
            raise ValueError('Wrong number of data points ...')
        from abipy.core.structure import Structure
        structure = Structure.from_sites(sites=sites)
        from abipy.core.mesh3d import Mesh3D
        mesh = Mesh3D(shape=[nx, ny, nz], vectors=uc_matrix)

        return structure, mesh, data
Esempio n. 38
0
    def __init__(self, filepath):
        super(DdbFile, self).__init__(filepath)

        self._header = self._parse_header()

        self._structure = Structure.from_abivars(**self.header)
        # Add Spacegroup (needed in guessed_ngkpt)
        # FIXME: has_timerev is always True
        spgid, has_timerev, h = 0, True, self.header
        self._structure.set_spacegroup(SpaceGroup(spgid, h.symrel, h.tnons, h.symafm, has_timerev))

        frac_coords = self._read_qpoints()
        self._qpoints = KpointList(self.structure.reciprocal_lattice, frac_coords, weights=None, names=None)

        # Guess q-mesh
        self._guessed_ngqpt = self._guess_ngqpt()
Esempio n. 39
0
def scf_for_phonons(structure, pseudos, kppa=None, ecut=None, pawecutdg=None, nband=None, accuracy="normal",
                    spin_mode="polarized", smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None,
                    shift_mode="Symmetric"):
    abiinput = scf_input(structure=structure, pseudos=pseudos, kppa=kppa, ecut=ecut, pawecutdg=pawecutdg, nband=nband,
                         accuracy=accuracy, spin_mode=spin_mode, smearing=smearing, charge=charge,
                         scf_algorithm=scf_algorithm, shift_mode=shift_mode)
    # set symmetrized k-point
    if shift_mode[0].lower() == 's':
        # need to convert to abipy structure to get the calc_shiftk method
        structure = Structure.from_sites(structure)
        shiftk = structure.calc_shiftk()
        abiinput.set_vars(shiftk=shiftk, nshiftk=len(shiftk))

    # enforce symmetries and add a buffer of bands to ease convergence with tolwfr
    abiinput.set_vars(chksymbreak=1, nbdbuf=4, tolwfr=1.e-22)

    return abiinput
Esempio n. 40
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)
Esempio n. 41
0
def display_structure(obj, **kwargs):
    """
    Use Jsmol to display a structure in the jupyter notebook.
    Requires `nbjsmol` notebook extension installed on the local machine.
    Install it with `pip install nbjsmol`. See also https://github.com/gmatteo/nbjsmol.

    Args:
        obj: Structure object or file with a structure or python object with a `structure` attribute.
        kwargs: Keyword arguments passed to `nbjsmol_display`
    """
    try:
        from nbjsmol import nbjsmol_display
    except ImportError as exc:
        raise ImportError(
            str(exc) + "\ndisplay structure requires nbjsmol package\n."
            "Install it with `pip install nbjsmol.`\n"
            "See also https://github.com/gmatteo/nbjsmol.")

    # Cast to structure, get string with cif data and pass it to nbjsmol.
    structure = Structure.as_structure(obj)
    return nbjsmol_display(structure.to(fmt="cif"), ext=".cif", **kwargs)
Esempio n. 42
0
def display_structure(obj, **kwargs):
    """
    Use Jsmol to display a structure in the jupyter notebook.
    Requires `nbjsmol` notebook extension installed on the local machine.
    Install it with `pip install nbjsmol`. See also https://github.com/gmatteo/nbjsmol.

    Args:
        obj: Structure object or file with a structure or python object with a `structure` attribute.
        kwargs: Keyword arguments passed to `nbjsmol_display`
    """
    try:
        from nbjsmol import nbjsmol_display
    except ImportError as exc:
        raise ImportError(str(exc) +
                          "\ndisplay structure requires nbjsmol package\n."
                          "Install it with `pip install nbjsmol.`\n"
                          "See also https://github.com/gmatteo/nbjsmol.")

    # Cast to structure, get string with cif data and pass it to nbjsmol.
    structure = Structure.as_structure(obj)
    return nbjsmol_display(structure.to(fmt="cif"), ext=".cif", **kwargs)
Esempio n. 43
0
def cube_read_structure_mesh_data(file):
    with open(file, 'r') as fh:
        # The two first lines are comments
        for ii in range(2):
            fh.readline()
        # Number of atoms
        natoms = int(fh.readline().split()[0])
        # The next three lines give the mesh and the vectors
        sp = fh.readline().split()
        nx = int(sp[0])
        dvx = np.array([float(sp[ii]) for ii in range(1, 4)]) * bohr_to_angstrom
        sp = fh.readline().split()
        ny = int(sp[0])
        dvy = np.array([float(sp[ii]) for ii in range(1, 4)]) * bohr_to_angstrom
        sp = fh.readline().split()
        nz = int(sp[0])
        dvz = np.array([float(sp[ii]) for ii in range(1, 4)]) * bohr_to_angstrom
        uc_matrix = np.array([nx*dvx, ny*dvy, nz*dvz])
        sites = []
        lattice = Lattice(uc_matrix)
        for ii in range(natoms):
            sp = fh.readline().split()
            cc = np.array([float(sp[ii]) for ii in range(2, 5)]) * bohr_to_angstrom
            sites.append(PeriodicSite(int(sp[0]), coords=cc, lattice=lattice, to_unit_cell=False,
                                      coords_are_cartesian=True))
        data = np.zeros((nx, ny, nz))
        ii = 0
        for line in fh:
            for val in line.split():
                data[ii//(ny*nz), (ii//nz)%ny, ii%nz] = float(val)
                ii += 1
        data = data / (bohr_to_angstrom ** 3)
        if ii != nx*ny*nz:
            raise ValueError('Wrong number of data points ...')
        from abipy.core.structure import Structure
        structure = Structure.from_sites(sites=sites)
        from abipy.core.mesh3d import Mesh3D
        mesh = Mesh3D(shape=[nx, ny, nz], vectors=uc_matrix)

        return structure, mesh, data
Esempio n. 44
0
def half_heusler(a, species):
    # fcc lattice with 3 atoms as basis
    # prototype: AgAlGe
    # See also http://www.cryst.ehu.es/cgi-bin/cryst/programs/nph-wp-list?gnum=216
    lattice = 0.5 * float(a) * np.array([0, 1, 1, 1, 0, 1, 1, 1, 0])

    frac_coords = np.reshape(
        [
            0,
            0,
            0,  # Ag
            0.5,
            0.5,
            0.5,  # Al
            1 / 4,
            1 / 4,
            1 / 4,  # Ge
            #3/4, 3/4, 3/4,  # Z
        ],
        (3, 3))

    return Structure(lattice, species, frac_coords, coords_are_cartesian=False)
Esempio n. 45
0
    def test_si(self):
        """Testing wyckoff positions for Si2"""
        si = Structure.from_file(abidata.cif_file("si.cif"))
        ss = si.site_symmetries
        repr(ss)
        str(ss)
        assert ss.to_string(verbose=2)
        df = ss.get_wyckoff_dataframe(verbose=2)
        self.assert_equal(np.array(df["xfrac"].values, dtype=float), [0, 0.25])
        self.assert_equal(np.array(df["yfrac"].values, dtype=float), [0, 0.25])
        self.assert_equal(np.array(df["zfrac"].values, dtype=float), [0, 0.25])
        #0  -43m (#31) nsym:24                  0                  0                  0
        #1  -43m (#31) nsym:24  0.250000000000000  0.250000000000000  0.250000000000000

        df = ss.get_tensor_rank2_dataframe(verbose=2)
        ref = ["Tzz", "Tzz"]
        self.assert_equal(df["Txx"].values, ref)
        self.assert_equal(df["Tyy"].values, ref)
        ref = ["-Tzz/3", "-Tzz/3"]
        self.assert_equal(df["Txy"].values, ref)
        self.assert_equal(df["Txz"].values, ref)
        self.assert_equal(df["Tyz"].values, ref)
Esempio n. 46
0
    def work_for_pseudo(self, pseudo, kppa=3000, maxene=250, ecut=None, pawecutdg=None,
                        spin_mode="unpolarized", include_soc=False,
                        tolwfr=1.e-12, smearing="fermi_dirac:0.1 eV", workdir=None, manager=None, **kwargs):
        """
        Returns a :class:`Work` object from the given pseudopotential.

        Args:
            pseudo: :class:`Pseudo` object.
            kppa: Number of k-points per reciprocal atom.
            ecut: Cutoff energy in Hartree
            pawecutdg: Cutoff energy of the fine grid (PAW only)
            spin_mode: Spin polarization option
            tolwfr: Tolerance on the residuals.
            smearing: Smearing technique.
            workdir: Working directory.
            manager: :class:`TaskManager` object.
            kwargs: Extra variables passed to Abinit.
        """
        if pseudo.ispaw and pawecutdg is None:
            raise ValueError("pawecutdg must be specified for PAW calculations.")

        if pseudo.xc != self._dfdb.xc:
            raise ValueError(
                "Pseudo xc differs from the XC used to instantiate the factory\n"
                "Pseudo: %s, Database: %s" % (pseudo.xc, self._dfdb.xc))
        try:
            cif_path = self.get_cif_path(pseudo.symbol)
        except Exception as exc:
            raise self.Error(str(exc))

        # DO NOT CHANGE THE STRUCTURE REPORTED IN THE CIF FILE.
        structure = Structure.from_file(cif_path, primitive=False)

        return GhostsWork(
            structure, pseudo, kppa, maxene,
            spin_mode=spin_mode, include_soc=include_soc, tolwfr=tolwfr, smearing=smearing,
            ecut=ecut, pawecutdg=pawecutdg, ecutsm=0.5,
            workdir=workdir, manager=manager, **kwargs)
Esempio n. 47
0
def AbinitNscfTasks(structure,
                    kpoints,
                    ecut,
                    nscf_bands,
                    nscf_kpoints=None,
                    **kwargs):
    from abipy.core.structure import Structure
    from abipy.abio.factories import scf_for_phonons
    from pymatgen.core.units import bohr_to_ang

    #extract pseudos
    pseudo_list = []
    for atype, (mass, pseudo) in structure['atypes'].items():
        pseudo_list.append(pseudo)
    pseudo_table = kwargs.pop("pseudo_table", pseudo_list)

    #create a PwInput file just to read the ibrav from structure
    qe_input = PwIn.from_structure_dict(structure)
    lattice, coords, species = qe_input.get_cell()
    lattice = [[col * bohr_to_ang for col in row] for row in lattice]
    structure = Structure(lattice, species, coords)

    #create an AbinitInput file from structure
    spin_mode = kwargs.pop('spin_mode', 'unpolarized')
    smearing = kwargs.pop('smearing', 'nosmearing')
    inp = scf_for_phonons(structure,
                          pseudo_table,
                          spin_mode=spin_mode,
                          smearing=smearing,
                          ecut=ecut / 2)

    return AbinitNscfTasksFromAbinitInput(inp,
                                          kpoints,
                                          ecut,
                                          nscf_bands,
                                          nscf_kpoints=nscf_kpoints,
                                          **kwargs)
Esempio n. 48
0
 def get_abistructure_from_abiref(basename):
     """Return an Abipy |Structure| from the basename of one of the reference files."""
     from abipy.core.structure import Structure
     return Structure.as_structure(abidata.ref_file(basename))
Esempio n. 49
0
def bse_with_mdf_inputs(structure, pseudos, 
                        scf_kppa, nscf_nband, nscf_ngkpt, nscf_shiftk, 
                        ecuteps, bs_loband, bs_nband, soenergy, mdf_epsinf, 
                        ecut=None, pawecutdg=None, 
                        exc_type="TDA", bs_algo="haydock", accuracy="normal", spin_mode="polarized", 
                        smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None):
    """
    Returns a :class:`AbinitInput` object that performs a GS + NSCF + Bethe-Salpeter calculation.
    The self-energy corrections are approximated with the scissors operator.
    The screening in modeled with the model dielectric function.

    Args:
        structure: :class:`Structure` object.
        pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object.
        scf_kppa: Defines the sampling used for the SCF run.
        nscf_nband: Number of bands included in the NSCF run.
        nscf_ngkpt: Divisions 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.
        ecut: cutoff energy in Ha (if None, ecut is initialized from the pseudos according to accuracy)
        pawecutdg: cutoff energy in Ha for PAW double-grid (if None, pawecutdg is initialized from the pseudos
            according to accuracy)
        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.
    """
    structure = Structure.as_structure(structure)
    multi = MultiDataset(structure, pseudos, ndtset=3)

    # Set the cutoff energies.
    d = _find_ecut_pawecutdg(ecut, pawecutdg, multi.pseudos)
    multi.set_vars(ecut=d.ecut, ecutwfn=d.ecut, pawecutdg=d.pawecutdg)

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

    scf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm=scf_algorithm, 
                                   charge=charge, nband=None, fband=None)

    if scf_electrons.nband is None:
        scf_electrons.nband = _find_scf_nband(structure, multi.pseudos, scf_electrons)

    multi[0].set_vars(scf_ksampling.to_abivars())
    multi[0].set_vars(scf_electrons.to_abivars())
    multi[0].set_vars(_stopping_criterion("scf", accuracy))

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

    nscf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm={"iscf": -2},
                                    charge=charge, nband=nscf_nband, fband=None)

    multi[1].set_vars(nscf_ksampling.to_abivars())
    multi[1].set_vars(nscf_electrons.to_abivars())
    multi[1].set_vars(_stopping_criterion("nscf", accuracy))

    # BSE calculation.
    exc_ham = aobj.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)

    multi[2].set_vars(nscf_ksampling.to_abivars())
    multi[2].set_vars(nscf_electrons.to_abivars())
    multi[2].set_vars(exc_ham.to_abivars())
    #multi[2].set_vars(_stopping_criterion("nscf", accuracy))

    # TODO: Cannot use istwfk != 1.
    multi.set_vars(istwfk="*1")

    return multi
Esempio n. 50
0
 def _get_structure(self, obj):
     """Extract the structure from the input object."""
     return Structure.as_structure(obj)
Esempio n. 51
0
 def structure(self):
     """Returns the :class:`Structure` associated to this dataset."""
     # TODO: Avoid calling Structure.from_abivars, find a way to cache the object and invalidate it.
     return Structure.from_abivars(self.allvars)
Esempio n. 52
0
    def _parse_dims(self):
        """
        Parse basic dimensions and get structure from the header of the file.
        """
        self.version, self._structure, self.grid_size = None, None, None
        # Init dictionary with parameters.
        self.params_section = OrderedDict([
            (s, OrderedDict())
            for s in ("MAIN", "WANNIERISE", "PLOTTING", "DISENTANGLE")
        ])
        params_done = False

        for iln, line in enumerate(self.lines):
            # Check for any warnings
            if 'Warning' in line:
                self.warnings.append(line)
                continue

            if "Time to read parameters" in line:
                params_done = True
                continue

            # Get release string.
            if "Release:" in line:
                i = line.find("Release:")
                self.version = line[i:].split()[1]
                continue

            # Parse lattice.
            if "Lattice Vectors" in line and self._structure is None:
                #              Lattice Vectors (Ang)
                #    a_1     0.000000   2.715473   2.715473
                #    a_2     2.715473   0.000000   2.715473
                #    a_3     2.715473   2.715473   0.000000
                lattice = np.array([
                    list(map(float, self.lines[iln + j].split()[1:]))
                    for j in range(1, 4)
                ])
                continue

            # Parse atoms.
            if "|   Site   " in line and self._structure is None:
                # *----------------------------------------------------------------------------*
                # |   Site       Fractional Coordinate          Cartesian Coordinate (Ang)     |
                # +----------------------------------------------------------------------------+
                # | Si   1   0.00000   0.00000   0.00000   |    0.00000   0.00000   0.00000    |
                # | Si   2   0.25000   0.25000   0.25000   |    1.35774   1.35774   1.35774    |
                # *----------------------------------------------------------------------------*
                frac_coords, species = [], []
                i = iln + 2
                while True:
                    l = self.lines[i].strip()
                    if l.startswith("*"): break
                    i += 1
                    tokens = l.replace("|", " ").split()
                    species.append(tokens[0])
                    frac_coords.append(np.array(list(map(float, tokens[2:5]))))

                self._structure = Structure(lattice, species, frac_coords)
                continue

            # Parse kmesh.
            if "Grid size" in line:
                # Grid size =  2 x  2 x  2      Total points =    8
                tokens = line.split("=")[1].split("Total")[0].split("x")
                self.grid_size = np.array(list(map(int, tokens)))
                continue

            if not params_done and any(sname in line
                                       for sname in self.params_section):
                #*---------------------------------- MAIN ------------------------------------*
                #|  Number of Wannier Functions               :                 4             |
                #|  Wavefunction spin channel                 :                up             |
                #*----------------------------------------------------------------------------*
                # Use params_done to avoid parsing the second section with WANNIERISE
                key = line.replace("*", "").replace("-", "").strip()
                i = iln + 1
                l = self.lines[i].strip()
                while not l.startswith("*-"):
                    tokens = [s.strip() for s in l.replace("|", "").split(":")]
                    self.params_section[key][tokens[0]] = tokens[1]
                    i += 1
                    l = self.lines[i].strip()
                continue

        # Extract important metadata from sections and convert from string.
        self.nwan = int(
            self.params_section["MAIN"]["Number of Wannier Functions"])
        if self.params_section["DISENTANGLE"].get("Using band disentanglement",
                                                  "F") == "T":
            self.use_disentangle = True
Esempio n. 53
0
 def read_structure(self):
     from abipy.core.structure import Structure
     return Structure.from_file(self.path)
Esempio n. 54
0
def ebands_input(structure, pseudos, 
                 kppa=None, nscf_nband=None, ndivsm=15, 
                 ecut=None, pawecutdg=None, scf_nband=None, accuracy="normal", spin_mode="polarized",
                 smearing="fermi_dirac:0.1 eV", charge=0.0, scf_algorithm=None, dos_kppa=None):
    """
    Returns a :class:`AbinitInput` for band structure calculations.

    Args:
        structure: :class:`Structure` object.
        pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object.
        kppa: Defines the sampling used for the SCF run. Defaults to 1000 if not given.
        nscf_nband: Number of bands included in the NSCF run. Set to scf_nband + 10 if None.
        ndivsm: Number of divisions used to sample the smallest segment of the k-path.
        ecut: cutoff energy in Ha (if None, ecut is initialized from the pseudos according to accuracy)
        pawecutdg: cutoff energy in Ha for PAW double-grid (if None, pawecutdg is initialized from the pseudos
            according to accuracy)
        scf_nband: Number of bands for SCF run. If scf_nband is None, nband is automatically initialized
            from the list of pseudos, the structure and the smearing option.
        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: Scalar or List of integers with the number of k-points per atom
            to be used for the computation of the DOS (None if DOS is not wanted).
    """
    structure = Structure.as_structure(structure)

    if dos_kppa is not None and not isinstance(dos_kppa, (list, tuple)):
        dos_kppa = [dos_kppa]

    multi = MultiDataset(structure, pseudos, ndtset=2 if dos_kppa is None else 2 + len(dos_kppa))

    # Set the cutoff energies.
    multi.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, multi.pseudos))

    # SCF calculation.
    kppa = _DEFAULTS.get("kppa") if kppa is None else kppa
    scf_ksampling = aobj.KSampling.automatic_density(structure, kppa, chksymbreak=0)
    scf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm=scf_algorithm, 
                                   charge=charge, nband=scf_nband, fband=None)

    if spin_mode=="polarized":
        multi[0].set_autospinat()

    if scf_electrons.nband is None:
        scf_electrons.nband = _find_scf_nband(structure, multi.pseudos, scf_electrons, multi[0].get('spinat', None))

    multi[0].set_vars(scf_ksampling.to_abivars())
    multi[0].set_vars(scf_electrons.to_abivars())
    multi[0].set_vars(_stopping_criterion("scf", accuracy))

    # Band structure calculation.
    nscf_ksampling = aobj.KSampling.path_from_structure(ndivsm, structure)
    nscf_nband = scf_electrons.nband + 10 if nscf_nband is None else nscf_nband
    nscf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm={"iscf": -2},
                                    charge=charge, nband=nscf_nband, fband=None)

    multi[1].set_vars(nscf_ksampling.to_abivars())
    multi[1].set_vars(nscf_electrons.to_abivars())
    multi[1].set_vars(_stopping_criterion("nscf", accuracy))

    # DOS calculation with different values of kppa.
    if dos_kppa is not None:
        for i, kppa in enumerate(dos_kppa):
            dos_ksampling = aobj.KSampling.automatic_density(structure, kppa, chksymbreak=0)
            #dos_ksampling = aobj.KSampling.monkhorst(dos_ngkpt, shiftk=dos_shiftk, chksymbreak=0)
            dos_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm={"iscf": -2},
                                           charge=charge, nband=nscf_nband) 
            dt = 2 + i
            multi[dt].set_vars(dos_ksampling.to_abivars())
            multi[dt].set_vars(dos_electrons.to_abivars())
            multi[dt].set_vars(_stopping_criterion("nscf", accuracy))

    return multi
Esempio n. 55
0
def structure_from_cif(filename):
    """
    Returnn an Abipy structure from the basename of the cif file in data/cifs.
    """
    return Structure.from_file(cif_file(filename))
Esempio n. 56
0
def g0w0_with_ppmodel_inputs(structure, pseudos, 
                            kppa, nscf_nband, ecuteps, ecutsigx,
                            ecut=None, pawecutdg=None,
                            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):
    """
    Returns a :class:`AbinitInput` object that performs G0W0 calculations with the plasmon pole approximation.

    Args:
        structure: Pymatgen structure.
        pseudos: List of filenames or list of :class:`Pseudo` objects or :class:`PseudoTable` object.
        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.
        ecut: cutoff energy in Ha (if None, ecut is initialized from the pseudos according to accuracy)
        pawecutdg: cutoff energy in Ha for PAW double-grid (if None, pawecutdg is initialized 
            from the pseudos according to accuracy)
        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 compute the
            QP energies for all the point in the IBZ and one band above and one band below the Fermi level.
    """
    structure = Structure.as_structure(structure)
    multi = MultiDataset(structure, pseudos, ndtset=4)

    # Set the cutoff energies.
    multi.set_vars(_find_ecut_pawecutdg(ecut, pawecutdg, multi.pseudos))

    scf_ksampling = aobj.KSampling.automatic_density(structure, kppa, chksymbreak=0)
    scf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm=scf_algorithm, 
                                   charge=charge, nband=None, fband=None)

    if scf_electrons.nband is None:
        scf_electrons.nband = _find_scf_nband(structure, multi.pseudos, scf_electrons)

    multi[0].set_vars(scf_ksampling.to_abivars())
    multi[0].set_vars(scf_electrons.to_abivars())
    multi[0].set_vars(_stopping_criterion("scf", accuracy))

    nscf_ksampling = aobj.KSampling.automatic_density(structure, kppa, chksymbreak=0)
    nscf_electrons = aobj.Electrons(spin_mode=spin_mode, smearing=smearing, algorithm={"iscf": -2},
                                    charge=charge, nband=nscf_nband, fband=None)

    multi[1].set_vars(nscf_ksampling.to_abivars())
    multi[1].set_vars(nscf_electrons.to_abivars())
    multi[1].set_vars(_stopping_criterion("nscf", accuracy))
    # nbdbuf

    # Screening.
    if scr_nband is None: scr_nband = nscf_nband
    screening = aobj.Screening(ecuteps, scr_nband, w_type="RPA", sc_mode="one_shot",
                               hilbert=None, ecutwfn=None, inclvkb=inclvkb)

    multi[2].set_vars(nscf_ksampling.to_abivars())
    multi[2].set_vars(nscf_electrons.to_abivars())
    multi[2].set_vars(screening.to_abivars())
    multi[2].set_vars(_stopping_criterion("screening", accuracy)) # Dummy
    #scr_strategy = ScreeningStrategy(scf_strategy, nscf_strategy, screening)

    # Sigma.
    if sigma_nband is None: sigma_nband = nscf_nband
    self_energy = aobj.SelfEnergy("gw", "one_shot", sigma_nband, ecutsigx, screening,
                             gw_qprange=gw_qprange, ppmodel=ppmodel)

    multi[3].set_vars(nscf_ksampling.to_abivars())
    multi[3].set_vars(nscf_electrons.to_abivars())
    multi[3].set_vars(self_energy.to_abivars())
    multi[3].set_vars(_stopping_criterion("sigma", accuracy)) # Dummy
    #sigma_strategy = aobj.SelfEnergyStrategy(scf_strategy, nscf_strategy, scr_strategy, self_energy)

    # TODO: Cannot use istwfk != 1.
    multi.set_vars(istwfk="*1")

    return multi