Exemplo n.º 1
0
    def __init__(self, label, LOC):
        self.label = label
        self.LOC = LOC
        E, V = [], []
        alldos = []

        # get all the data from the atoms. E, V and DOS
        for calculator in LOC:
            with calculator as calc:
                atoms = calc.get_atoms()
                E.append(atoms.get_potential_energy())
                V.append(atoms.get_volume())
                
                dos = DOS(calc, width=0.2)
                n = dos.get_dos()
                e = dos.get_energies()
                
                alldos.append((e, n))

        E = np.array(E)
        V = np.array(V)

        self.E = E
        self.V = V
        self.alldos = alldos

        # this is the range we fit over
        self.T = np.linspace(400, 1500, 20)
Exemplo n.º 2
0
def get_dos(prefix, outdir=None, schema=None, width=0.01, npts=100):
    """
    This function returns an DOS object from an output xml Espresso file containing the
    results of a DOS calculation.

    :param prefix: prefix of saved output files
    :param outdir: directory containing the input data. Default to the value of \
    ESPRESSO_TMPDIR environment variable if set or current directory ('.') otherwise
    :param schema: the XML schema to be used to read and validate the XML output file
    :param width: width of the gaussian to be used for the DOS (in eV)
    :param npts:  number of points of the DOS
    :return: a DOS object
    """
    label = get_label(prefix, outdir)

    # set a simple calculator, only to read the xml file results
    calcul = PostqeCalculator(atoms=None, label=label, schema=schema)
    # define the Atoms structure reading the xml file
    atoms = get_atoms_from_xml_output(calcul.label + ".xml", schema=schema)
    atoms.set_calculator(calcul)
    # read the results
    atoms.calc.read_results()

    # Create a DOS object with width= eV and npts points
    dos = DOS(calcul, width=width, npts=npts)

    return dos
Exemplo n.º 3
0
import matplotlib.pyplot as plt
import numpy as np
from ase.dft import DOS
import pylab as plt
a = 3.9  # approximate lattice constant
b = a / 2.
bulk = Atoms([Atom('Pd', (0.0, 0.0, 0.0))],
             cell=[(0, b, b),
                   (b, 0, b),
                   (b, b, 0)])
kpts = [8, 10, 12, 14, 16, 18, 20]
calcs = [Vasp('bulk/pd-dos-k{0}-ismear-5'.format(k),
              encut=300,
              xc='PBE',
              kpts=[k, k, k],
              atoms=bulk) for k in kpts]
Vasp.wait(abort=True)
for calc in calcs:
    # this runs the calculation
    if calc.potential_energy is not None:
        dos = DOS(calc, width=0.2)
        d = dos.get_dos() + k / 4.0
        e = dos.get_energies()
        plt.plot(e, d, label='k={0}'.format(k))
    else:
        pass
plt.xlabel('energy (eV)')
plt.ylabel('DOS')
plt.legend()
plt.savefig('images/pd-dos-k-convergence-ismear-5.png')
plt.show()
Exemplo n.º 4
0
def get_bandstructure(self,
                      kpts_path=None,
                      kpts_nintersections=10):
    """Calculate band structure along :param kpts_path:

    :param list kpts_path: list of tuples of (label, k-point) to
    calculate path on.

    :param int kpts_nintersections: is the number of points between
    points in band structures. More makes the bands smoother. See
    :func:`jasp_kpts.write_kpoints`.

    >>> from jasp import *
    >>> from jasp.jasp_bandstructure import *

    >>> with jasp('bulk/tio2/step3') as calc:
    ...     n, bands, p = calc.get_bandstructure(kpts_path=[('$\Gamma$',[0.0, 0.0, 0.0]),
                                                            ('X',[0.5, 0.5, 0.0]),
                                                            ('X',[0.5, 0.5, 0.0]),
                                                            ('M',[0.0, 0.5, 0.5]),
                                                            ('M',[0.0, 0.5, 0.5]),
                                                            ('$\Gamma$',[0.0, 0.0, 0.0])])

    >>> p.savefig('images/tio2-bandstructure-dos.png')

    returns (npoints, band_energies, fighandle)

    """

    kpts = [k[1] for k in kpts_path]
    labels = [k[0] for k in kpts_path]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()

    # run in non-selfconsistent directory
    cwd = os.getcwd()
    base, end = os.path.split(cwd)
    wd = cwd + '/bandstructure'
    self.clone(wd)

    with jasp(wd,
              kpts=kpts,
              kpts_nintersections=kpts_nintersections,
              reciprocal=True,
              nsw=0,  # no ionic updates required
              isif=None,
              ibrion=None,
              debug=logging.DEBUG,
              icharg=11) as calc:

        calc.calculate()

        fig = plt.figure()
        with open('EIGENVAL') as f:
            line1 = f.readline()
            line2 = f.readline()
            line3 = f.readline()
            line4 = f.readline()
            comment = f.readline()
            unknown, npoints, nbands = [int(x) for x in f.readline().split()]

            blankline = f.readline()

            band_energies = [[] for i in range(nbands)]

            for i in range(npoints):
                x, y, z, weight = [float(x) for x in f.readline().split()]

                for j in range(nbands):
                    fields = f.readline().split()
                    id, energy = int(fields[0]), float(fields[1])
                    band_energies[id-1].append(energy)
                blankline = f.readline()
            f.close()
            ax1 = plt.subplot(121)
            for i in range(nbands):
                plt.plot(range(npoints), np.array(band_energies[i]) - ef)

            ax = plt.gca()
            ax.set_xticks([])  # no tick marks
            plt.xlabel('k-vector')
            plt.ylabel('Energy (eV)')

            nticks = len(labels)/2 + 1
            ax.set_xticks(np.linspace(0, npoints, nticks))
            L = []
            L.append(labels[0])
            for i in range(2, len(labels)):
                if i % 2 == 0:
                    L.append(labels[i])
                else:
                    pass
            L.append(labels[-1])
            ax.set_xticklabels(L)
            plt.axhline(0, c='r')

    plt.subplot(122, sharey=ax1)
    plt.plot(d, e)
    plt.axhline(0, c='r')
    plt.ylabel('energy (eV)')
    plt.xlabel('DOS')

    plt.subplots_adjust(wspace=0.26)
    plt.show()
    return (npoints, band_energies, fig)
Exemplo n.º 5
0
from ase.lattice.cubic import FaceCenteredCubic
from ase.dft import DOS
atoms = FaceCenteredCubic(directions=[[0,1,1],
                                      [1,0,1],
                                      [1,1,0]],
                                      size=(1,1,1),
                                      symbol='Ni')
atoms[0].magmom = 1
with jasp('bulk/Ni-PBE',
          ismear=-5,
          kpts=(5,5,5),
          xc='PBE',
          ispin=2,lorbit=11,
          atoms=atoms) as calc:
    print 'PBE energy:   ',atoms.get_potential_energy()
    dos = DOS(calc, width=0.2)
    e_pbe = dos.get_energies()
    d_pbe = dos.get_dos()
    calc.clone('bulk/Ni-PBE0')
    calc.clone('bulk/Ni-HSE06')
with jasp('bulk/Ni-PBE0') as calc:
     calc.set(lhfcalc=True,
              algo='D',
              time=0.4)
     atoms = calc.get_atoms()
     print 'PBE0 energy:  ',atoms.get_potential_energy()
     dos = DOS(calc, width=0.2)
     e_pbe0 = dos.get_energies()
     d_pbe0 = dos.get_dos()
with jasp('bulk/Ni-HSE06') as calc:
     calc.set(lhfcalc=True,
Exemplo n.º 6
0
def get_bandstructure(self, kpts_path=None, kpts_nintersections=10):
    """Calculate band structure along :param kpts_path:

    :param list kpts_path: list of tuples of (label, k-point) to
    calculate path on.

    :param int kpts_nintersections: is the number of points between
    points in band structures. More makes the bands smoother. See
    :func:`jasp_kpts.write_kpoints`.

    >>> from jasp import *
    >>> from jasp.jasp_bandstructure import *

    >>> with jasp('bulk/tio2/step3') as calc:
    ...     n, bands, p = calc.get_bandstructure(kpts_path=[('$\Gamma$',[0.0, 0.0, 0.0]),
                                                            ('X',[0.5, 0.5, 0.0]),
                                                            ('X',[0.5, 0.5, 0.0]),
                                                            ('M',[0.0, 0.5, 0.5]),
                                                            ('M',[0.0, 0.5, 0.5]),
                                                            ('$\Gamma$',[0.0, 0.0, 0.0])])

    >>> p.savefig('images/tio2-bandstructure-dos.png')

    returns (npoints, band_energies, fighandle)

    """

    kpts = [k[1] for k in kpts_path]
    labels = [k[0] for k in kpts_path]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()

    # run in non-selfconsistent directory
    cwd = os.getcwd()
    base, end = os.path.split(cwd)
    wd = cwd + '/bandstructure'
    self.clone(wd)

    with jasp(
            wd,
            kpts=kpts,
            kpts_nintersections=kpts_nintersections,
            reciprocal=True,
            nsw=0,  # no ionic updates required
            isif=None,
            ibrion=None,
            debug=logging.DEBUG,
            icharg=11) as calc:

        calc.calculate()

        fig = plt.figure()
        with open('EIGENVAL') as f:
            line1 = f.readline()
            line2 = f.readline()
            line3 = f.readline()
            line4 = f.readline()
            comment = f.readline()
            unknown, npoints, nbands = [int(x) for x in f.readline().split()]

            blankline = f.readline()

            band_energies = [[] for i in range(nbands)]

            for i in range(npoints):
                x, y, z, weight = [float(x) for x in f.readline().split()]

                for j in range(nbands):
                    fields = f.readline().split()
                    id, energy = int(fields[0]), float(fields[1])
                    band_energies[id - 1].append(energy)
                blankline = f.readline()
            f.close()
            ax1 = plt.subplot(121)
            for i in range(nbands):
                plt.plot(range(npoints), np.array(band_energies[i]) - ef)

            ax = plt.gca()
            ax.set_xticks([])  # no tick marks
            plt.xlabel('k-vector')
            plt.ylabel('Energy (eV)')

            nticks = len(labels) / 2 + 1
            ax.set_xticks(np.linspace(0, npoints, nticks))
            L = []
            L.append(labels[0])
            for i in range(2, len(labels)):
                if i % 2 == 0:
                    L.append(labels[i])
                else:
                    pass
            L.append(labels[-1])
            ax.set_xticklabels(L)
            plt.axhline(0, c='r')

    plt.subplot(122, sharey=ax1)
    plt.plot(d, e)
    plt.axhline(0, c='r')
    plt.ylabel('energy (eV)')
    plt.xlabel('DOS')

    plt.subplots_adjust(wspace=0.26)
    plt.show()
    return (npoints, band_energies, fig)
Exemplo n.º 7
0
p = atoms.get_potential_energy()
save(result_file, '4th calculation \n total energy : {0} eV, {1} eV/atom'.format(p, p/len(atoms)))

tm = atoms.get_magnetic_moment()
m = atoms.get_magnetic_moments()
save(result_file, 'total magnetic moment : {0} mB {1} mB/atom '.format(tm, tm/len(atoms)))
save(result_file, 'magnetic moment: {0}'.format(m))


vdos = VaspDos()
vdos.read_doscar('DOSCAR')
print vdos.efermi
print vdos.site_dos(0,0)


dos = DOS(calc, width=0.05)

d = dos.get_dos()
up = dos.get_dos(0)
down = dos.get_dos(1)

e = dos.get_energies()

plt.plot(e,d, label='total')
plt.plot(e,up, label='spin-up')
plt.plot(e,-1.0*down, label='spin-down')

plt.grid(True)
plt.xlim(-20, 20)
plt.ylim(-10, 10)
plt.legend()
Exemplo n.º 8
0
from vasp import Vasp
from ase.dft import DOS
# This seems very slow...
calc = Vasp('bulk/pd-dos-k20-ismear-5')
print DOS(calc, width=0.2)
Exemplo n.º 9
0
import matplotlib.pyplot as plt
import numpy as np
from ase.dft import DOS
import pylab as plt
a = 3.9  # approximate lattice constant
b = a / 2.
bulk = Atoms([Atom('Pd', (0.0, 0.0, 0.0))],
             cell=[(0, b, b), (b, 0, b), (b, b, 0)])
kpts = [8, 10, 12, 14, 16, 18, 20]
calcs = [
    Vasp('bulk/pd-dos-k{0}-ismear-5'.format(k),
         encut=300,
         xc='PBE',
         kpts=[k, k, k],
         atoms=bulk) for k in kpts
]
Vasp.wait(abort=True)
for calc in calcs:
    # this runs the calculation
    if calc.potential_energy is not None:
        dos = DOS(calc, width=0.2)
        d = dos.get_dos() + k / 4.0
        e = dos.get_energies()
        plt.plot(e, d, label='k={0}'.format(k))
    else:
        pass
plt.xlabel('energy (eV)')
plt.ylabel('DOS')
plt.legend()
plt.savefig('images/pd-dos-k-convergence-ismear-5.png')
plt.show()
Exemplo n.º 10
0
def get_bandstructure(self,
                      kpts_path=None,
                      kpts_nintersections=10,
                      show=False):
    """Calculate band structure along :param kpts_path:
    :param list kpts_path: list of tuples of (label, k-point) to
      calculate path on.
    :param int kpts_nintersections: is the number of points between
      points in band structures. More makes the bands smoother.

    returns (npoints, band_energies, fighandle)

    """
    self.update()
    self.stop_if(self.potential_energy is None)

    kpts = [k[1] for k in kpts_path]
    labels = [k[0] for k in kpts_path]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()

    # run in non-selfconsistent directory

    wd = os.path.join(self.directory, 'bandstructure')
    self.clone(wd)

    calc = vasp.Vasp(wd)
    calc.set(kpts=kpts,
             kpts_nintersections=kpts_nintersections,
             reciprocal=True,
             nsw=0,  # no ionic updates required
             isif=None,
             ibrion=None,
             icharg=11)

    calc.update()

    if calc.potential_energy is None:
        return None, None, None

    fig = plt.figure()
    with open(os.path.join(wd, 'EIGENVAL')) as f:
        # skip 5 lines
        f.readline()
        f.readline()
        f.readline()
        f.readline()
        f.readline()
        unknown, npoints, nbands = [int(x) for x in f.readline().split()]

        f.readline()  # skip line

        band_energies = [[] for i in range(nbands)]

        for i in range(npoints):
            x, y, z, weight = [float(x) for x in f.readline().split()]

            for j in range(nbands):
                fields = f.readline().split()
                id, energy = int(fields[0]), float(fields[1])
                band_energies[id - 1].append(energy)
            f.readline()  # skip line

    ax1 = plt.subplot(121)
    for i in range(nbands):
        plt.plot(range(npoints), np.array(band_energies[i]) - ef)

    ax = plt.gca()
    ax.set_xticks([])  # no tick marks
    plt.xlabel('k-vector')
    plt.ylabel('Energy (eV)')

    nticks = len(labels) / 2 + 1
    ax.set_xticks(np.linspace(0, npoints, nticks))
    L = []
    L.append(labels[0])
    for i in range(2, len(labels)):
        if i % 2 == 0:
            L.append(labels[i])
        else:
            pass
    L.append(labels[-1])
    ax.set_xticklabels(L)
    plt.axhline(0, c='r')

    plt.subplot(122, sharey=ax1)
    plt.plot(d, e)
    plt.axhline(0, c='r')
    plt.ylabel('energy (eV)')
    plt.xlabel('DOS')

    plt.subplots_adjust(wspace=0.26)
    if show:
        plt.show()
    return (npoints, band_energies, fig)
Exemplo n.º 11
0
def get_bandstructure(self,
                      kpts_path=None,
                      kpts_nintersections=10,
                      show=False,
                      ylim=None,
                      outdir=None,
                      outfile=None):
    """Calculate band structure along :param kpts_path:
    :param list kpts_path: list of tuples of (label, k-point) to
      calculate path on.
    :param int kpts_nintersections: is the number of points between
      points in band structures. More makes the bands smoother.

    returns (npoints, band_energies, fighandle, Energy gap, Convection band minimum, valance band maximum)

    """
    prevdir = os.getcwd()  #store for later use

    self.update()
    self.stop_if(self.potential_energy is None)

    kpts = [k[1] for k in kpts_path]
    labels = [k[0] for k in kpts_path]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()

    # run in non-selfconsistent directory

    wd = os.path.join(self.directory, 'bandstructure')

    if not os.path.exists(wd):
        self.clone(wd)

        calc = Vasp(wd)
        calc.set(
            kpts=kpts,
            kpts_nintersections=kpts_nintersections,
            reciprocal=True,
            nsw=0,  # no ionic updates required
            isif=None,
            ibrion=None,
            icharg=11)

        calc.update()

        if calc.potential_energy is None:
            return None, None, None, None, None, None

    else:  # I don't think this will work unless the calculation is complete!

        archiveKpts = os.path.join(wd, 'KPOINTS_old')
        originalKpts = os.path.join(wd, 'KPOINTS')
        if not os.path.exists(
                archiveKpts):  # archive the original KPOINTS file
            shutil.copy(originalKpts, archiveKpts)

        with open(archiveKpts, 'r') as kpts_infile:  # get lines of old KPOINTS
            KPtsLines = kpts_infile.readlines()

        # Append labels for high-symmetry points to lines of the KPOINTS file
        reject_chars = '$'
        for idx, label in enumerate(labels):
            newlabel = label
            for ch in reject_chars:
                newlabel = newlabel.replace(ch, '')

            KPtsLines[4 + idx] = KPtsLines[4 + idx][:-1] + f' ! {newlabel}\n'

        # Write a new version of the k-points file
        with open(originalKpts, 'w') as kpts_outfile:
            for line in KPtsLines:
                kpts_outfile.write(line)

        EIGFILE = os.path.join(wd, 'EIGENVAL')

        npoints, band_energies, fig = makeBandPlot(
            EIGFILE,
            labels,
            ef=ef,
            ylim=ylim,
            d=d,
            e=e,  # DOS data
            show=show)

        # Run sumo-bandplot, if it exists
        check_sumo = sp.run(['which', 'sumo-bandplot'], capture_output=True)
        found_sumo = not check_sumo.stdout == b''
        found_band_data = os.path.exists(os.path.join(wd, 'vasprun.xml'))

        if found_sumo and found_band_data:
            os.chdir(wd)
            sumo_cmd = ['sumo-bandplot']
            run_sumo = sp.run(sumo_cmd, capture_output=True)
            if outfile is not None:
                shutil.copy('band.pdf', outfile)
            else:
                outfile = 'band.pdf'
            if outdir is not None:
                target = os.path.join(outdir, outfile)
                shutil.copy(outfile, target)
            else:
                target = os.path.join(os.getcwd(), outfile)

            Egap, Ecbm, Evbm = read_bandstats()

        else:
            print('sumo-bandplot not found. No band plot generated.')
            target = None
            Egap, Ecbm, Evbm = None, None, None

        #reset dir
        os.chdir(prevdir)

        return (npoints, band_energies, fig, Egap, Ecbm, Evbm)
Exemplo n.º 12
0
def get_bandstructure_v02(self,
                          kpts_path=None,
                          kpts_nintersections=None,
                          show=False,
                          outdir=None,
                          outfile=None):
    """Calculate a hybrid band structure along :param kpts_path:
    :param list kpts_path: list of tuples of (label, k-point) to
      calculate path on.
    :param int kpts_nintersections: is the number of points between
      points in band structures. More makes the bands smoother.

    returns (npoints, band_energies, fighandle)

    This is designed to provide a function to calculate the band structure
    according to the procedure 2 provided by the VASP Wiki:
    https://www.vasp.at/wiki/index.php/Si_bandstructure#Procedure_2:_0-weight_.28Fake.29_SC_procedure_.28PBE_.26_Hybrids.29
    """
    """
    Our first job will be to copy the working directory to a subdirectory.
    This will happen on the first invocation of get_bandstructure_v02()
    """

    self.update()
    self.stop_if(self.potential_energy is None)

    kx, ky, kz, labels, label_idx = interpolate_kpath(kpts_path,
                                                      kpts_nintersections)

    num_new_k_points = len(kx)
    '''
    kx = np.linspace(kpts[0][0], kpts[1][0], kpts_nintersections)
    ky = np.linspace(kpts[0][1], kpts[1][1], kpts_nintersections)
    kz = np.linspace(kpts[0][2], kpts[1][2], kpts_nintersections)
    '''

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()
    '''
    By now, our initial DFT calculation should be complete. It should have
    produced an IBZKPT file.
    '''
    wd = os.path.join(self.directory, 'bandstructure')

    if not os.path.exists(wd):
        # I think: clone works if no subsequent calcs have been run
        # This branch should be taken on the first invocation of
        # get_bandstructure_v02
        self.clone(wd)

        # I think: Vasp() works if no subsequent calcs have been run
        calc = Vasp(wd)
        '''
        Now we create a file "KPOINTS_HSE_bands" update the KPOINTS file by doing the following:
        (1) Use the IBZKPT file for the KPOINTS file
        (2) Add desired zero-weight k-points
        (3) Update the number of total k-points
        
        Here's a link to a video of a seminar where the additional k-points are
        discussed: https://youtu.be/OQhRYzWAGfk?t=2389
        - These points correspond to positions along the k-point path we desire
        '''

        # Deleting the old KPOINTS file is probably a bad thing
        # old_kpts = os.path.join( calc.directory, 'KPOINTS')
        # os.remove(old_kpts)

        # Read the automatically-generated k-points from IBZKPT
        IBZKPT = os.path.join(calc.directory, 'IBZKPT')
        with open(IBZKPT, 'rt') as infile:
            infile.readline()
            nk_old = int(infile.readline().split()[0])
            # print(nk_old)
            print(f'Found {nk_old} k-points in IBZKPT.')
            print(
                f'There are {num_new_k_points} additional zero-weight k-points.'
            )
            print('Reading the original k-points...')
            original_k_lines = []
            for idx in range(0, nk_old + 1):
                original_k_lines.append(infile.readline())
            # print(': {0}'.format(original_k_lines[idx]))

        total_k_points = nk_old + num_new_k_points

        print(f'There are a total of {total_k_points} k-points.')

        # Obtain text lines for the original k-points
        HSE_lines = [
            'Explicit k-point list\n', ' ' * 6 + f'{total_k_points}\n'
        ]
        for line in original_k_lines:
            HSE_lines.append(line)

        # Make text lines for the new k points
        for idx in range(0, num_new_k_points):
            line_str = '{0:15.12f} {1:15.12f} {2:15.12f} 0.0\n'.format(
                kx[idx], ky[idx], kz[idx])
            HSE_lines.append(line_str)

        # for line in HSE_lines:
        #    print(line)

        # Write the 'KPOINTS_HSE_bands' file
        tgt = os.path.join(calc.directory, 'KPOINTS')  # 'KPOINTS_HSE_bands')
        with open(tgt, 'w') as KPTSfile:
            for line in HSE_lines:
                KPTSfile.write(line)
        """
        Refer to:
        https://www.vasp.at/wiki/index.php/Si_bandstructure#Hybrid_calculation_using_a_suitably_modified_KPOINTS_file
        
        Here, the VASP example suggests adding the following to the INCAR file:
        ## HSE
        LHFCALC = .TRUE. ; HFSCREEN = 0.2 ; AEXX = 0.25
        ALGO = D ; TIME = 0.4 ; LDIAG = .TRUE.
        
        Notes: 
    
        validate.py does not appear to have a case for LHFCALC, HFSCREEN, or
        AEXX. This might necessitate (for now), the simple and dirty hack of
        simply appending text to the INCAR file. This, then, means another
        dirty hack of running VASP in the directory in question apart from
        ASE.

        LHFCALC (https://www.vasp.at/wiki/index.php/LHFCALC)
           specifies whether HF/DFT hybrid functional-type calculations are
           performed.
           Default: False

        HFSCREEN (https://www.vasp.at/wiki/index.php/HFSCREEN)
           specifies the range-separation parameter in range separated hybrid
           functionals.

        AEXX (https://www.vasp.at/wiki/index.php/AEXX)
           Default: AEXX = 0.25 if LHFCALC=.TRUE., 0 otherwise

        The ALGO (https://www.vasp.at/wiki/index.php/ALGO) Wiki page does not
           list a "D" property. There is a "Damped" setting, however.

        The LDIAG (https://www.vasp.at/wiki/index.php/LDIAG) page says that
           TRUE is the default value, so I'm going to refrain from adding this.
        """
        HSE_settings = 'LHFCALC = .TRUE. ; HFSCREEN = 0.2; ALGO = D\nICHARG = 11'

        tgt = os.path.join(calc.directory, 'INCAR')
        with open(tgt, 'a') as infile:
            infile.write(HSE_settings)

        # Create and run a subprocess that invokes
        if self.parameters.get('lsorbit'):
            runfile = 'runvasp_ncl.py'
        else:
            runfile = 'runvasp.py'

        CWD = os.getcwd()
        VASPDIR = calc.directory
        from .vasprc import VASPRC
        module = VASPRC['module']
        script = """#!/bin/bash
module load {module}

source ~/.bashrc # added by EPB - slight issue with "module load intel"

cd {CWD}
cd {VASPDIR}  # this is the vasp directory

{runfile}     # this is the vasp command
#end""".format(**locals())

        jobname = 'HSE_BandCalc'
        cmdlist = ['{0}'.format(VASPRC['queue.command'])]
        cmdlist += ['-o', VASPDIR]
        cmdlist += [option for option in VASPRC['queue.options'].split()]
        cmdlist += [
            '-N', '{0}'.format(jobname), '-l',
            'walltime={0}'.format(VASPRC['queue.walltime']), '-l',
            'nodes={0}:ppn={1}'.format(VASPRC['queue.nodes'],
                                       VASPRC['queue.ppn']), '-l',
            'mem={0}'.format(VASPRC['queue.mem']), '-M', VASPRC['user.email']
        ]
        p = sp.Popen(cmdlist,
                     stdin=sp.PIPE,
                     stdout=sp.PIPE,
                     stderr=sp.PIPE,
                     universal_newlines=True)

        out, err = p.communicate(script)

        return None

    else:
        """
        This should happen on the second invocation of get_bandstructure_v02.
        Here, we will add labels for the zero-weight k-points.
        """

        # Read the automatically-generated k-points from IBZKPT
        IBZKPT = os.path.join(wd, 'IBZKPT')
        with open(IBZKPT, 'rt') as infile:
            infile.readline()
            nk_old = int(infile.readline().split()[0])
            # print(nk_old)
            print(f'Found {nk_old} k-points in IBZKPT.')

        kx, ky, kz, spec_k_labels, label_idx = interpolate_kpath(
            kpts_path, kpts_nintersections)

        num_new_k_points = len(kx)

        import shutil

        archive_KPOINTS = os.path.join(wd, 'KPOINTS_original')
        if not os.path.exists(archive_KPOINTS):
            shutil.copy(os.path.join(wd, 'KPOINTS'), archive_KPOINTS)

        with open(archive_KPOINTS, 'r') as infile:
            KPTS_Lines = infile.readlines()

        for idx, label in enumerate(spec_k_labels):
            label = label.replace('$', '')
            newk_idx = label_idx[idx]
            line_with_label = KPTS_Lines[3 + nk_old +
                                         newk_idx][:-1] + f' {label}\n'
            KPTS_Lines[3 + nk_old + newk_idx] = line_with_label

        with open(os.path.join(wd, 'KPOINTS'), 'w') as KPOINTSfile:
            for line in KPTS_Lines:
                KPOINTSfile.write(line)

        # Run sumo-bandplot, if it exists
        check_sumo = sp.run(['which', 'sumo-bandplot'], capture_output=True)
        found_sumo = not check_sumo.stdout == b''
        found_band_data = os.path.exists(os.path.join(wd, 'vasprun.xml'))

        if found_sumo and found_band_data:
            os.chdir(wd)
            sumo_cmd = ['sumo-bandplot']
            run_sumo = sp.run(sumo_cmd, capture_output=True)
            if outfile is not None:
                shutil.copy('band.pdf', outfile)
            else:
                outfile = 'band.pdf'
            if outdir is not None:
                target = os.path.join(outdir, outfile)
                shutil.copy(outfile, target)
            else:
                target = os.path.join(os.getcwd(), outfile)

            Egap, Ecbm, Evbm = read_bandstats()

        else:
            print('sumo-bandplot not found. No band plot generated.')
            target = None
            Egap, Ecbm, Evbm = None, None, None

    return {'file': target, 'Egap': Egap, 'Ecbm': Ecbm, 'Evbm': Evbm}
Exemplo n.º 13
0
def get_supercell_bandstructure_ppc(self,
                                    kpts_path=None,
                                    kpts_nintersections=None,
                                    supercell_size=[1, 1, 1],
                                    unit_cell=[[1.0, 0, 0], [0, 1.0, 0],
                                               [0.0, 0.0, 0.0]],
                                    show=False):
    """Calculate band structure along :param kpts_path:
    :param list kpts_path: list of tuples of (label, k-point) to
      calculate path on.
    :param int kpts_nintersections: is the number of points between
      points in band structures. More makes the bands smoother.
    :param list supercell_size: this lists the size of the supercell
      [nx ny nz] as multiples of the unit cell in the ordinal directions
    :param list unit_cell: list of unit cell vectors

    This version uses PyProcar for k-path preparation and unfolding.
       See https://romerogroup.github.io/pyprocar/index.html

    
    
    returns (npoints, band_energies, fighandle)

    """
    self.update()
    self.stop_if(self.potential_energy is None)

    M = [[1.0 * supercell_size[0], 0.0, 0.0],
         [0.0, 1.0 * supercell_size[1], 0.0],
         [0.0, 0.0, 1.0 * supercell_size[2]]]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()

    kpts = [k[1] for k in kpts_path]
    labels = [k[0] for k in kpts_path]

    # by now, the self-consistent calculation is complete
    # run in non-selfconsistent directory
    wd = os.path.join(self.directory, 'bandstructure')

    if not os.path.exists(wd):
        self.clone(wd)

        calc = Vasp(wd)

        # this next line actually writes a K-points file, but we're
        # going to use pyprocar to overwrite it
        calc.set(
            kpts=kpts,
            kpts_nintersections=10,
            reciprocal=True,
            nsw=0,  # no ionic updates required
            isif=None,
            ibrion=None,
            icharg=11,
            lorbit=12)

        os.remove(os.path.join(wd, 'KPOINTS'))

        # Let's try generating the default k-points path
        # Now I need to learn how to set the k-path using pyprocar
        #   see:
        import pyprocar as ppc
        ppc.kpath(os.path.join(wd, 'POSCAR'),
                  os.path.join(wd, 'KPOINTS'),
                  supercell_matrix=np.diag(supercell_size))

        # calc.update()
        # we'll just launch VASP - skip the calc.update()

        # Create and run a subprocess that invokes
        if self.parameters.get('lsorbit'):
            runfile = 'runvasp_ncl.py'
        else:
            runfile = 'runvasp.py'
        CWD = os.getcwd()
        VASPDIR = calc.directory
        from .vasprc import VASPRC
        module = VASPRC['module']
        script = """#!/bin/bash
module load {module}

source ~/.bashrc # added by EPB - slight issue with "module load intel"

cd {CWD}
cd {VASPDIR}  # this is the vasp directory

{runfile}     # this is the vasp command
#end""".format(**locals())

        jobname = 'SCBands'
        cmdlist = ['{0}'.format(VASPRC['queue.command'])]
        cmdlist += ['-o', VASPDIR]
        cmdlist += [option for option in VASPRC['queue.options'].split()]
        cmdlist += [
            '-N', '{0}'.format(jobname), '-l',
            'walltime={0}'.format(VASPRC['queue.walltime']), '-l',
            'nodes={0}:ppn={1}'.format(VASPRC['queue.nodes'],
                                       VASPRC['queue.ppn']), '-l',
            'mem={0}'.format(VASPRC['queue.mem']), '-M', VASPRC['user.email']
        ]
        p = sp.Popen(cmdlist,
                     stdin=sp.PIPE,
                     stdout=sp.PIPE,
                     stderr=sp.PIPE,
                     universal_newlines=True)

        out, err = p.communicate(script)
        '''

        return None, None, None

        # if calc.potential_energy is None:
        #    return None, None, None
     

    else: # I don't think this will work unless the calculation is complete!

        os.chdir(wd)

        import pyprocar

        pyprocar.unfold(
            fname='PROCAR',
            poscar='POSCAR',
            outcar='OUTCAR',
            supercell_matrix=np.diag(supercell_size),
            ispin=None, # None for non-spin polarized calculation. For spin polarized case, ispin=1: up, ispin=2: down
            efermi=None,
            shift_efermi=True,
            elimit=(-2, 2), # kticks=[0, 36, 54, 86, 110, 147, 165, 199], knames=['$\Gamma$', 'K', 'M', '$\Gamma$', 'A', 'H', 'L', 'A'],
            print_kpts=False,
            show_band=True,
            width=4,
            color='blue',
            savetab='unfolding.csv',
            savefig='unfolded_band.png',
            exportplt=False)

        return None, None, None
        '''
        from unfold import unfold

        WaveSuper = unfold(M=M, wavecar='WAVECAR')
        sw = WaveSuper.spectral_weight(kpath_uc)

        from unfold import EBS_cmaps
        e0, sf = WaveSuper.spectral_function(nedos=4000)
        # or show the effective band structure with colormap
        EBS_cmaps(
            kpath_sc,
            unit_cell,
            e0,
            sf,
            nseg=nseg,  #  eref=-4.01,
            show=False)  #,
        # ylim=(-3, 4))
        '''

        plt.savefig('unfolded_bandstructure.png')


        '''
        # In the fol
        archiveKpts = os.path.join(wd, 'KPOINTS_old')
        originalKpts = os.path.join(wd, 'KPOINTS')
        if not os.path.exists(
                archiveKpts):  # archive the original KPOINTS file
            shutil.copy(originalKpts, archiveKpts)

        with open(archiveKpts, 'r') as kpts_infile:  # get lines of old KPOINTS
            KPtsLines = kpts_infile.readlines()

        # Append labels for high-symmetry points to lines of the KPOINTS file
        reject_chars = '$'
        for idx, label in enumerate(labels):
            newlabel = label
            for ch in reject_chars:
                newlabel = newlabel.replace(ch, '')

            KPtsLines[4 + idx] = KPtsLines[4 + idx][:-1] + f' ! {newlabel}\n'

        # Write a new version of the k-points file
        with open(originalKpts, 'w') as kpts_outfile:
            for line in KPtsLines:
                kpts_outfile.write(line)

        # This is John Kitchin's original band structure visualization
        fig = plt.figure()
        with open(os.path.join(wd, 'EIGENVAL')) as f:
            # skip 5 lines
            f.readline()
            f.readline()
            f.readline()
            f.readline()
            f.readline()
            unknown, npoints, nbands = [int(x) for x in f.readline().split()]

            f.readline()  # skip line

            band_energies = [[] for i in range(nbands)]

            for i in range(npoints):
                x, y, z, weight = [float(x) for x in f.readline().split()]

                for j in range(nbands):
                    fields = f.readline().split()
                    id, energy = int(fields[0]), float(fields[1])
                    band_energies[id - 1].append(energy)
                f.readline()  # skip line

        ax1 = plt.subplot(121)
        for i in range(nbands):
            plt.plot(list(range(npoints)), np.array(band_energies[i]) - ef)

        ax = plt.gca()
        ax.set_xticks([])  # no tick marks
        plt.xlabel('k-vector')
        plt.ylabel('Energy (eV)')

        nticks = len(labels) / 2 + 1
        ax.set_xticks(np.linspace(0, npoints, nticks))
        L = []
        L.append(labels[0])
        for i in range(2, len(labels)):
            if i % 2 == 0:
                L.append(labels[i])
            else:
                pass
        L.append(labels[-1])
        ax.set_xticklabels(L)
        plt.axhline(0, c='r')

        plt.subplot(122, sharey=ax1)
        plt.plot(d, e)
        plt.axhline(0, c='r')
        plt.ylabel('energy (eV)')
        plt.xlabel('DOS')

        plt.subplots_adjust(wspace=0.26)
        if show:
            plt.show()
        return (npoints, band_energies, fig)
Exemplo n.º 14
0
def get_supercell_bandstructure(self,
                                kpts_path=None,
                                kpts_nintersections=None,
                                supercell_size=[1, 1, 1],
                                unit_cell=[[1.0, 0, 0], [0, 1.0, 0],
                                           [0.0, 0.0, 1.0]],
                                show=False,
                                imagedir=None,
                                imageprefix=None,
                                eref=None,
                                ymin=None,
                                ymax=None,
                                lsorb=False):
    """Calculate band structure along :param kpts_path:
    :param list kpts_path: list of tuples of (label, k-point) to
      calculate path on.
    :param int kpts_nintersections: is the number of points between
      points in band structures. More makes the bands smoother.
    :param list supercell_size: this lists the size of the supercell
      [nx ny nz] as multiples of the unit cell in the ordinal directions
    :param list unit_cell: list of unit cell vectors

    returns (npoints, band_energies, fighandle)

    """
    self.update()
    self.stop_if(self.potential_energy is None)

    # Determine whether the colinear (vasp_std)  or non-colinear (vasp_ncl) is
    #    to be used
    if self.parameters.get('lsorbit'):
        runfile = 'runvasp_ncl.py'
    else:
        runfile = 'runvasp.py'
    '''
       I'm following the procedure for creating a k-path in the supercell
           https://github.com/QijingZheng/VaspBandUnfolding#band-unfolding-1
    '''
    # The tranformation matrix between supercell and primitive cell.
    M = [[1.0 * supercell_size[0], 0.0, 0.0],
         [0.0, 1.0 * supercell_size[1], 0.0],
         [0.0, 0.0, 1.0 * supercell_size[2]]]

    print(M)

    from unfold import find_K_from_k, make_kpath, removeDuplicateKpoints

    # Extract unit-cell k-points from kpts_path
    uc_k_pts_bare = [k[1] for k in kpts_path]
    nseg = 30  # points per segment
    kpath_uc = make_kpath(uc_k_pts_bare, nseg=nseg)  # interpolated uc k-path

    # Map UC (=PC) k-points to SC k-points
    Kpath_sc = []
    for k_uc in kpath_uc:
        K, g = find_K_from_k(k_uc, M)
        Kpath_sc.append(K)  # add a weight to K

    Kpath = removeDuplicateKpoints(Kpath_sc)  # this is a numpy.ndarray

    # I convert this to a list because the Vasp wrapper prefers a kpts list
    # Also, the Vasp wrapper wants a weight for each K point
    Kpath_list = [list(np.append(K, 1.0)) for K in Kpath]

    # Extract (unit cel) labels from kpts_path
    labels = [k[0] for k in kpts_path]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()
    print(f'Fermi energy: {ef:8.3f} eV')

    # run in non-selfconsistent directory
    wd = os.path.join(self.directory, 'bandstructure')

    if not os.path.exists(wd):
        self.clone(wd)

        calc = Vasp(wd)
        # don't set kpts_nintersections - avoid line mode
        calc.set(
            kpts=Kpath_list,
            reciprocal=True,
            nsw=0,  # no ionic updates required
            ismear=0,
            sigma=0.1,
            isif=None,
            ibrion=None,
            icharg=11,
            lorbit=12)

        calc.update()  # updates the calculation files

        # The manual calculation might be unnecessary because
        # of the calc.update()
        '''
        CWD = os.getcwd()
        VASPDIR = calc.directory
        from .vasprc import VASPRC
        module = VASPRC['module']
        script = """#!/bin/bash
module load {module}

source ~/.bashrc # added by EPB - slight issue with "module load intel"

cd {CWD}
cd {VASPDIR}  # this is the vasp directory

{runfile}     # this is the vasp command
#end""".format(**locals())

        jobname = 'SCBands'
        cmdlist = ['{0}'.format(VASPRC['queue.command'])]
        cmdlist += ['-o', VASPDIR]
        cmdlist += [option for option in VASPRC['queue.options'].split()]
        cmdlist += ['-N', '{0}'.format(jobname),
                    '-l', 'walltime={0}'.format(VASPRC['queue.walltime']),
                    '-l', 'nodes={0}:ppn={1}'.format(VASPRC['queue.nodes'],
                                                     VASPRC['queue.ppn']),
                    '-l', 'mem={0}'.format(VASPRC['queue.mem']),
                    '-M', VASPRC['user.email']]
        p = sp.Popen(cmdlist,
                     stdin=sp.PIPE,
                     stdout=sp.PIPE,
                     stderr=sp.PIPE,
                     universal_newlines=True)

        out, err = p.communicate(script)

        '''

        return None, None

    else:  # I don't think this will work unless the calculation is complete!

        os.chdir(wd)

        if imagedir is None:
            imagedir = os.getcwd()
        if imageprefix is None:
            imageprefix = 'unfolded_bandstructure'

        from unfold import unfold

        # nseg = len(kpts_path) -1

        WaveSuper = unfold(M=M, wavecar='WAVECAR', lsorbit=lsorb)
        sw = WaveSuper.spectral_weight(kpath_uc)

        from unfold import EBS_cmaps, EBS_scatter
        e0, sf = WaveSuper.spectral_function(nedos=4000)

        if eref is None:
            eref = ef
        if ymin is None:
            ymin = ef - 5
        if ymax is None:
            ymax = ef + 5
        print('The unit cell vectors are:')
        print(unit_cell)
        # Show the effective band structure with a scatter plot
        EBS_scatter(kpath_uc,
                    unit_cell,
                    sw,
                    nseg=nseg,
                    eref=eref,
                    ylim=(ymin, ymax),
                    factor=5,
                    kpath_label=labels)

        scatterplot = os.path.join(imagedir, imageprefix) + '_scatter_plot.png'
        plt.savefig(scatterplot)

        plt.close('all')
        # or show the effective band structure with colormap
        EBS_cmaps(kpath_uc,
                  unit_cell,
                  e0,
                  sf,
                  nseg=nseg,
                  eref=eref,
                  show=False,
                  ylim=(ymin, ymax),
                  kpath_label=labels)

        colormap = os.path.join(imagedir, imageprefix) + '_colormap.png'
        plt.savefig(colormap)

        return scatterplot, colormap
Exemplo n.º 15
0
                          symbol='Ni')
atoms[0].magmom = 1
calc = Vasp(
    'bulk/Ni-PBE',
    ismear=-5,
    kpts=[5, 5, 5],
    xc='PBE',
    ispin=2,
    lorbit=11,
    lwave=True,
    lcharg=True,  # store for reuse
    atoms=atoms)
e = atoms.get_potential_energy()
print('PBE energy:   ', e)
calc.stop_if(e is None)
dos = DOS(calc, width=0.2)
e_pbe = dos.get_energies()
d_pbe = dos.get_dos()
calc.clone('bulk/Ni-PBE0')
calc.set(xc='pbe0')
atoms = calc.get_atoms()
pbe0_e = atoms.get_potential_energy()
if atoms.get_potential_energy() is not None:
    dos = DOS(calc, width=0.2)
    e_pbe0 = dos.get_energies()
    d_pbe0 = dos.get_dos()
## HSE06
calc = Vasp('bulk/Ni-PBE')
calc.clone('bulk/Ni-HSE06')
calc.set(xc='hse06')
atoms = calc.get_atoms()
Exemplo n.º 16
0
import numpy as np

from ase.dft import DOS

class MyCalc:
    def get_eigenvalues(self, kpt=0, spin=0):
        return np.random.uniform(-5.0, 2.0, 90)
    def get_k_point_weights(self):
        return [1.0]
    def get_number_of_spins(self):
        return 1
    def get_fermi_level(self):
        return 0.0

calc = MyCalc()
dos = DOS(calc, width=0.2)
d = dos.get_dos()
e = dos.get_energies()

import matplotlib
matplotlib.use('Agg')
import pylab as plt
plt.figure(figsize=(5, 4))
plt.plot(e, d)
plt.xlabel('energy [eV]')
plt.ylabel('DOS')
plt.savefig('dos.png')


Exemplo n.º 17
0
def get_bandstructure(self,
                      kpts_path=None,
                      kpts_nintersections=10,
                      show=False):
    """Calculate band structure along :param kpts_path:
    :param list kpts_path: list of tuples of (label, k-point) to
      calculate path on.
    :param int kpts_nintersections: is the number of points between
      points in band structures. More makes the bands smoother.

    returns (npoints, band_energies, fighandle)

    """
    self.update()
    self.stop_if(self.potential_energy is None)

    kpts = [k[1] for k in kpts_path]
    labels = [k[0] for k in kpts_path]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()

    # run in non-selfconsistent directory

    wd = os.path.join(self.directory, 'bandstructure')
    self.clone(wd)

    calc = vasp.Vasp(wd)
    calc.set(
        kpts=kpts,
        kpts_nintersections=kpts_nintersections,
        reciprocal=True,
        nsw=0,  # no ionic updates required
        isif=None,
        ibrion=None,
        icharg=11)

    calc.update()

    if calc.potential_energy is None:
        return None, None, None

    fig = plt.figure()
    with open(os.path.join(wd, 'EIGENVAL')) as f:
        # skip 5 lines
        f.readline()
        f.readline()
        f.readline()
        f.readline()
        f.readline()
        unknown, npoints, nbands = [int(x) for x in f.readline().split()]

        f.readline()  # skip line

        band_energies = [[] for i in range(nbands)]

        for i in range(npoints):
            x, y, z, weight = [float(x) for x in f.readline().split()]

            for j in range(nbands):
                fields = f.readline().split()
                id, energy = int(fields[0]), float(fields[1])
                band_energies[id - 1].append(energy)
            f.readline()  # skip line

    ax1 = plt.subplot(121)
    for i in range(nbands):
        plt.plot(range(npoints), np.array(band_energies[i]) - ef)

    ax = plt.gca()
    ax.set_xticks([])  # no tick marks
    plt.xlabel('k-vector')
    plt.ylabel('Energy (eV)')

    nticks = len(labels) / 2 + 1
    ax.set_xticks(np.linspace(0, npoints, nticks))
    L = []
    L.append(labels[0])
    for i in range(2, len(labels)):
        if i % 2 == 0:
            L.append(labels[i])
        else:
            pass
    L.append(labels[-1])
    ax.set_xticklabels(L)
    plt.axhline(0, c='r')

    plt.subplot(122, sharey=ax1)
    plt.plot(d, e)
    plt.axhline(0, c='r')
    plt.ylabel('energy (eV)')
    plt.xlabel('DOS')

    plt.subplots_adjust(wspace=0.26)
    if show:
        plt.show()
    return (npoints, band_energies, fig)
Exemplo n.º 18
0
Arquivo: qe.py Projeto: costrouc/pyqe
 def get_dos(self, atoms=None, spin=None, width=0.1, npts=201):
     from ase.dft import DOS
     dos = DOS(self, width=width, npts=npts)
     return dos.get_energies(), dos.get_dos(spin)
Exemplo n.º 19
0
def makedb(calc,
           atoms=None,
           dbname='data.db',
           overwrite=False,
           dos=False,
           ados=False,
           keys={},
           data={},
           **kwargs):
    '''Make a modular database in calculator directory.
    This function generates useful key-value-pairs based
    on the directory path the calculation is stored in.

    i.e. .DFT/bulk=Ag/lattice=4.06/ will create two
    key-value-pairs: bulk=Ag and lattice=4.06

    more information on ASE database can be found here:
    https://wiki.fysik.dtu.dk/ase/ase/db/db.html'''

    # Do not run if database already exists
    if os.path.exists(dbname) and overwrite:
        os.unlink(dbname)

    # Get keys_value_pairs from directory name.
    # Collect only path names with '=' in them.
    path = [x for x in os.getcwd().split('/') if '=' in x]

    for key_value in path:
        key = key_value.split('=')[0]
        value = key_value.split('=')[1]

        # Try to recognize characters and convert to
        # specific data types for easy access later.
        if '.' in value:
            value = float(value)
        elif value.isdigit():
            value = int(value)
        elif value == 'False':
            value = bool(False)
        elif value == 'True':
            value = bool(True)
        else:
            value = str(value)

        # Add directory keys
        keys[key] = value

    # Add DFT parameters to key-value-pairs
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.float_params.items())))
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.int_params.items())))
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.bool_params.items())))
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.exp_params.items())))
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.special_params.items())))
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.string_params.items())))
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.bool_params.items())))
    data.update(dict(filter(lambda item: item[1] is not None,
                            calc.dict_params.items())))

    # Store k-points individually
    data['volume'] = atoms.get_volume()
    data['path'] = os.getcwd()

    try:
        data['fermi'] = calc.get_fermi_level()
    except(AttributeError):
        pass

    # Get the atoms object from the calculator
    if atoms is None:
        atoms = calc.get_atoms()

    if hasattr(calc, 'spinpol'):
        if calc.spinpol:
            data['final_magmom'] = atoms.get_magnetic_moment()

    if calc.is_neb():
        keys['image'] = int(calc.vaspdir.split('/')[-1])

    # Add density of state information to the dictionary
    if dos:
        dos = DOS(calc)
        d = dos.get_dos()
        e = dos.get_energies()

        data['DOS'] = {}
        data['DOS']['states'] = d
        data['DOS']['energy'] = e

        data['dband_center'] = np.trapz(e * d, e) / np.trapz(d, e)
        data['dband_width'] = np.trapz(e**2 * d, e) / np.trapz(d, e)

    # Add density of state information to the dictionary
    if ados:
        ados = VaspDos(efermi=calc.get_fermi_level())
        d = {}
        e = ados.energy

        for orb in ['s', 'p', 'd']:
            d[orb] = {}

            for atom in atoms:
                ind = calc.resort[atom.index]
                d[orb][ind] = ados.site_dos(ind, orb)

        data['ADOS'] = {}
        data['ADOS']['states'] = d
        data['ADOS']['energy'] = e

    # Add calculation time to key-value-pairs
    try:
        data['calc_time'] = float(get_elapsed_time(calc))
    except(AttributeError, IOError):
        data['calc_time'] = float(0.0)

    # Generate the JSON file
    db = connect(dbname)
    db.write(atoms=atoms, key_value_pairs=keys, data=data)
Exemplo n.º 20
0
def get_bandstructure(self,
                      kpts_path=None,
                      kpts_nintersections=10):

    kpts = [k[1] for k in kpts_path]
    labels = [k[0] for k in kpts_path]

    dos = DOS(self, width=0.2)
    d = dos.get_dos()
    e = dos.get_energies()

    ef = self.get_fermi_level()

    # run in non-selfconsistent directory
    cwd = os.getcwd()
    base, end = os.path.split(cwd)
    wd = cwd + '/bandstructure'
    self.clone(wd)

    with jasp(wd,
              kpts=kpts,
              kpts_nintersections=kpts_nintersections,
              reciprocal=True,
              nsw=0, # no ionic updates required
              isif=None,
              ibrion=None,
              debug=logging.DEBUG,
              icharg=11) as calc:

        calc.calculate()

        fig = plt.figure()
        with open('EIGENVAL') as f:
            line1 = f.readline()
            line2 = f.readline()
            line3 = f.readline()
            line4 = f.readline()
            comment = f.readline()
            unknown, npoints, nbands = [int(x) for x in f.readline().split()]

            blankline = f.readline()

            band_energies = [[] for i in range(nbands)]

            for i in range(npoints):
                x,y,z, weight = [float(x) for x in f.readline().split()]

                for j in range(nbands):
                    fields = f.readline().split()
                    id, energy = int(fields[0]), float(fields[1])
                    band_energies[id-1].append(energy)
                blankline = f.readline()
            f.close()
            ax1 = plt.subplot(121)
            for i in range(nbands):
                plt.plot(range(npoints), np.array(band_energies[i]) - ef)

            ax = plt.gca()
            ax.set_xticks([]) # no tick marks
            plt.xlabel('k-vector')
            plt.ylabel('Energy (eV)')

            nticks = len(labels)/2 + 1
            ax.set_xticks(np.linspace(0,npoints,nticks))
            L = []
            L.append(labels[0])
            for i in range(2,len(labels)):
                if i % 2 == 0:
                    L.append(labels[i])
                else:
                    pass
            L.append(labels[-1])
            ax.set_xticklabels(L)
            plt.axhline(0,c='r')

    plt.subplot(122, sharey=ax1)
    plt.plot(d,e)
    plt.axhline(0, c='r')
    plt.ylabel('energy (eV)')
    plt.xlabel('DOS')

    plt.subplots_adjust(wspace=0.26)
    plt.show()
    return (npoints, band_energies, fig)