Example #1
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument( '-i', '--ions', help='ion indices for band projection (default: sum over all ions)', nargs='+', type=int )
    parser.add_argument( '-s', '--spins', help='spin indices for band projection (default [ 1 ])', nargs='+', type=int, default=[ 1 ] )
    parser.add_argument( '-o', '--orbitals', help='orbital indices for band projection (default: sum over all orbitals)', nargs='+', type=int )
    parser.add_argument( '-e', '--efermi', help='set fermi energy as reference for energy scale', type=float, default=0.0 )
    parser.add_argument( '-l', '--l-angular-momentum', help='select all orbitals with angular momentum L for band projection. This supercedes the --orbitals option', choices=[ 's', 'p', 'd', 'f', 'all' ] )
    parser.add_argument( '-f', '--procar', help='PROCAR filename (default PROCAR)', type=str, default='PROCAR' )
    parser.add_argument( '--scaling', help='Energy scaling for band widths (default 0.2 eV)', type=float, default=0.2 )
    parser.add_argument( '-x', '--xscaling', help='Automatic scaling of x-axis using reciprocal lattice vectors read from OUTCAR', action='store_true', default=False )
    args = parser.parse_args()

    if args.l_angular_momentum:
        args.orbitals = orbitals_with_l( args.l_angular_momentum )

    if args.xscaling:
        reciprocal_lattice = reciprocal_lattice_from_outcar( 'OUTCAR' ) # Move reading the reciprocal lattice to procar.py
    else:
        reciprocal_lattice = None

    pcar = procar.Procar()
    pcar.read_from_file( args.procar )
    pcar.print_weighted_band_structure( spins = args.spins, 
                                        ions = args.ions, 
                                        orbitals = args.orbitals, 
                                        scaling = args.scaling, 
                                        e_fermi = args.efermi, 
                                        reciprocal_lattice = reciprocal_lattice )
Example #2
0
def main():
    parser = argparse.ArgumentParser(
        description=
        'Calculate an effective mass from a VASP PROCAR using a fitted quadratic'
    )
    parser.add_argument(
        '-k',
        '--k-points',
        help='index of k-points for calculating effective mass',
        nargs='+',
        type=int,
        required=True,
        action=minimum_length(2))
    parser.add_argument('-b',
                        '--band-index',
                        help='index of band for calculating effective mass',
                        type=int,
                        required=True)
    parser.add_argument('-f',
                        '--procar',
                        help='PROCAR filename (default PROCAR)',
                        type=str,
                        default='PROCAR')
    parser.add_argument('-v',
                        '--verbose',
                        help='Verbose output',
                        action='store_true')
    parser.add_argument('-o',
                        '--outcar',
                        help='OUTCAR filename (default OUTCAR)',
                        type=str,
                        default='OUTCAR')
    parser.add_argument(
        '-s',
        '--spin',
        help='select spin channel (default 1 / non-spin-polarised)',
        type=int,
        default='1')
    args = parser.parse_args()

    reciprocal_lattice = reciprocal_lattice_from_outcar(
        'OUTCAR')  # Move reading the reciprocal lattice to procar.py

    pcar = procar.Procar()
    pcar.read_from_file(args.procar)
    effective_mass = pcar.effective_mass_calc(
        k_point_indices=args.k_points,
        band_index=args.band_index,
        reciprocal_lattice=reciprocal_lattice,
        spin=args.spin,
        printing=args.verbose)
    print(effective_mass)
Example #3
0
    def __init__(self, outcar_path, procar_path, ignore=0):
        r"""
        Initialises an instance of the :class:`~effmass.inputs.Data` class and checks data using :meth:`check_data`.

        Args:
            outcar_path (str): The path to the OUTCAR file
            procar_path (str): The path to the PROCAR file
            ignore (int): The number of kpoints to ignore at the beginning of the bandstructure slice through kspace (useful for hybrid calculations where zero weightings are appended to a previous self-consistent calculation).
        
        Returns: 
            None.
        """
        assert (type(outcar_path) == str), "The OUTCAR path must be a string"
        assert (type(procar_path) == str), "The PROCAR path must be a string"
        assert (type(ignore) == int and ignore >= 0
                ), "The number of kpoints to ignore must be a positive integer"

        reciprocal_lattice = outcar.reciprocal_lattice_from_outcar(outcar_path)
        vasp_data = procar.Procar()
        vasp_data.read_from_file(procar_path)

        if vasp_data.calculation[
                'spin_polarised']:  # to account for the change in PROCAR format for calculations with 2 spin channels (1 k-point block ---> 2 k-point blocks)
            blocks = 2
        else:
            blocks = 1

        self.spin_channels = vasp_data.spin_channels
        self.number_of_kpoints = vasp_data.number_of_k_points - ignore
        self.number_of_bands = vasp_data.number_of_bands
        self.number_of_ions = vasp_data.number_of_ions
        self.kpoints = vasp_data.k_points[ignore:]
        self.energies = vasp_data.bands[self.number_of_bands * ignore:,
                                        1:].reshape(
                                            self.number_of_kpoints,
                                            self.number_of_bands * blocks).T
        self.occupancy = vasp_data.occupancy[self.number_of_bands * ignore:,
                                             1:].reshape(
                                                 self.number_of_kpoints,
                                                 self.number_of_bands *
                                                 blocks).T
        self.reciprocal_lattice = reciprocal_lattice * 2 * math.pi
        self.CBM = extrema._calc_CBM(self.occupancy, self.energies)
        self.VBM = extrema._calc_VBM(self.occupancy, self.energies)
        self.fermi_energy = (self.CBM + self.VBM) / 2
        self.dos = []
        self.integrated_dos = []
        self.check_data()
Example #4
0
    def __init__(self, outcar_path, procar_path, ignore=0, **kwargs):
        r"""
        Initialises an instance of the :class:`~effmass.inputs.Data` class and checks data using :meth:`check_data`.

        Args:
            outcar_path (str): The path to the OUTCAR file
            procar_path (:obj:`str` or :obj:`list`): The path(s) to one or more PROCAR files.
            
            ignore (int): The number of kpoints to ignore at the beginning of the bandstructure slice through kspace (useful for hybrid calculations where zero weightings are appended to a previous self-consistent calculation).
            **kwargs: Additional keyword arguments for reading the PROCAR file(s). 
 
        Returns: 
            None.
        """

        super().__init__()

        assert (type(outcar_path) == str), "The OUTCAR path must be a string"
        assert (type(ignore) == int and ignore >= 0
                ), "The number of kpoints to ignore must be a positive integer"

        reciprocal_lattice = outcar.reciprocal_lattice_from_outcar(outcar_path)
        if isinstance(procar_path, list):
            vasp_data = procar.Procar.from_files(procar_path, **kwargs)
        elif isinstance(procar_path, str):
            vasp_data = procar.Procar.from_file(procar_path, **kwargs)
        else:
            raise TypeError('procar_path must be a string or list of strings')

        self.spin_channels = vasp_data.spin_channels
        self.number_of_bands = vasp_data.number_of_bands

        number_of_kpoints = vasp_data.number_of_k_points
        vasp_data_energies = np.array( [ band.energy for band in np.ravel( vasp_data.bands ) ] )
        vasp_data_occupancies = np.array( [ band.occupancy for band in np.ravel( vasp_data.bands ) ] )
        if vasp_data.calculation['spin_polarised']: # to account for the change in PROCAR format for calculations with 2 spin channels (1 k-point block ---> 2 k-point blocks)
            energies = np.zeros([self.number_of_bands*2,number_of_kpoints]) # This is a very ugly way to slice 'n' dice. Should avoid creating new array and use array methods instead. But it does the job so will keep for now.
            for i in range(self.number_of_bands):
                energies[i] = vasp_data_energies.reshape(
                                            number_of_kpoints*2,  # factor of 2 for each kpoint block
                                            self.number_of_bands).T[i][:number_of_kpoints]
                energies[self.number_of_bands+i] = vasp_data_energies.reshape(
                                            number_of_kpoints*2,
                                            self.number_of_bands).T[i][number_of_kpoints:]
            occupancy = np.zeros([self.number_of_bands*2,number_of_kpoints])
            for i in range(self.number_of_bands):
                occupancy[i] = vasp_data_occupancies.reshape(
                                                 number_of_kpoints*2,
                                                 self.number_of_bands).T[i][:number_of_kpoints]
                occupancy[self.number_of_bands+i] = vasp_data_occupancies.reshape(
                                                 number_of_kpoints*2,
                                                 self.number_of_bands).T[i][number_of_kpoints:]
        else:
            energies = vasp_data_energies.reshape(
                                            number_of_kpoints,
                                            self.number_of_bands).T
            occupancy = vasp_data_occupancies.reshape(
                                                 number_of_kpoints,
                                                 self.number_of_bands).T

        # remove values which are from the self-consistent calculation prior to the bandstructure calculation (workflow for hybrid functionals)
        self.energies = np.delete(energies,list(range(ignore)),1)
        self.occupancy = np.delete(occupancy,list(range(ignore)),1)
        self.number_of_kpoints = number_of_kpoints - ignore

        # handle negative occupancy values
        if np.any(self.occupancy < 0):
            warnings.warn("One or more occupancies in your PROCAR file are negative. All negative occupancies will be set to zero.")
            self.occupancy[ self.occupancy < 0 ] = 0.0

        self.kpoints = np.array( [ kp.frac_coords 
            for kp in vasp_data.k_points[ignore:vasp_data.number_of_k_points] ] )
        self.reciprocal_lattice = reciprocal_lattice * 2 * math.pi
        self.CBM = extrema._calc_CBM(self.occupancy, self.energies)
        self.VBM = extrema._calc_VBM(self.occupancy, self.energies)
        self.fermi_energy = (self.CBM + self.VBM) / 2
        self.dos = []
        self.integrated_dos = []
        self.check_data(self.spin_channels, self.number_of_kpoints, self.number_of_bands, 
                   self.CBM, self.VBM, self.fermi_energy, self.occupancy)
Example #5
0
    return to_return[ l ]
 
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument( '-i', '--ions', help='ion indices for band projection (default: sum over all ions)', nargs='+', type=int )
    parser.add_argument( '-s', '--spins', help='spin indices for band projection (default [ 1 ])', nargs='+', type=int, default=[ 1 ] )
    parser.add_argument( '-o', '--orbitals', help='orbital indices for band projection (default: sum over all orbitals)', nargs='+', type=int )
    parser.add_argument( '-e', '--efermi', help='set fermi energy as reference for energy scale', type=float, default=0.0 )
    parser.add_argument( '-l', '--l-angular-momentum', help='select all orbitals with angular momentum L for band projection. This supercedes the --orbitals option', choices=[ 's', 'p', 'd', 'f', 'all' ] )
    parser.add_argument( '-f', '--procar', help='PROCAR filename (default PROCAR)', type=str, default='PROCAR' )
    parser.add_argument( '--scaling', help='Energy scaling for band widths (default 0.2 eV)', type=float, default=0.2 )
    parser.add_argument( '-x', '--xscaling', help='Automatic scaling of x-axis using reciprocal lattice vectors read from OUTCAR', action='store_true', default=False )
    args = parser.parse_args()

    if args.l_angular_momentum:
        args.orbitals = orbitals_with_l( args.l_angular_momentum )

    if args.xscaling:
        reciprocal_lattice = reciprocal_lattice_from_outcar( 'OUTCAR' ) # Move reading the reciprocal lattice to procar.py
    else:
        reciprocal_lattice = None

    pcar = procar.Procar()
    pcar.read_from_file( args.procar )
    pcar.print_weighted_band_structure( spins = args.spins, 
                                        ions = args.ions, 
                                        orbitals = args.orbitals, 
                                        scaling = args.scaling, 
                                        e_fermi = args.efermi, 
                                        reciprocal_lattice = reciprocal_lattice )
Example #6
0
    return to_return[ l ]
 
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument( '-i', '--ions', help='ion indices for band projection (default: sum over all ions)', nargs='+', type=int )
    parser.add_argument( '-s', '--spins', help='spin indices for band projection (default 0)', nargs='+', type=int, default=[ 0 ] )
    parser.add_argument( '-o', '--orbitals', help='orbital indices for band projection (default: sum over all orbitals)', nargs='+', type=int )
    parser.add_argument( '-e', '--efermi', help='set fermi energy as reference for energy scale', type=float, default=0.0 )
    parser.add_argument( '-l', '--l-angular-momentum', help='select all orbitals with angular momentum L for band projection. This supercedes the --orbitals option', choices=[ 's', 'p', 'd', 'f', 'all' ] )
    parser.add_argument( '-f', '--procar', help='PROCAR filename (default PROCAR)', type=str, default='PROCAR' )
    parser.add_argument( '--scaling', help='Energy scaling for band widths (default 0.2 eV)', type=float, default=0.2 )
    parser.add_argument( '-x', '--xscaling', help='Automatic scaling of x-axis using reciprocal lattice vectors read from OUTCAR', action='store_true', default=False )
    args = parser.parse_args()

    if args.l_angular_momentum:
        args.orbitals = orbitals_with_l( args.l_angular_momentum )

    if args.xscaling:
        reciprocal_lattice = reciprocal_lattice_from_outcar( 'OUTCAR' ) # Move reading the reciprocal lattice to procar.py
    else:
        reciprocal_lattice = None

    pcar = procar.Procar()
    pcar.read_from_file( args.procar )
    pcar.print_weighted_band_structure( spins = args.spins, 
                                        ions = args.ions, 
                                        orbitals = args.orbitals, 
                                        scaling = args.scaling, 
                                        e_fermi = args.efermi, 
                                        reciprocal_lattice = reciprocal_lattice )
Example #7
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '-i',
        '--ions',
        help='ion indices for band projection (default: sum over all ions)',
        nargs='+',
        type=int)
    parser.add_argument(
        '-s',
        '--spins',
        help='spin indices for band projection (default [ 1 ])',
        nargs='+',
        type=int,
        default=[1])
    parser.add_argument(
        '-o',
        '--orbitals',
        help=
        'orbital indices for band projection (default: sum over all orbitals)',
        nargs='+',
        type=int)
    parser.add_argument('-e',
                        '--efermi',
                        help='set fermi energy as reference for energy scale',
                        type=float,
                        default=0.0)
    parser.add_argument(
        '-l',
        '--l-angular-momentum',
        help=
        'select all orbitals with angular momentum L for band projection. This supercedes the --orbitals option',
        choices=['s', 'p', 'd', 'f', 'all'])
    parser.add_argument('-f',
                        '--procar',
                        help='PROCAR filename (default PROCAR)',
                        type=str,
                        default='PROCAR')
    parser.add_argument('--scaling',
                        help='Energy scaling for band widths (default 0.2 eV)',
                        type=float,
                        default=0.2)
    parser.add_argument(
        '-x',
        '--xscaling',
        help=
        'Automatic scaling of x-axis using reciprocal lattice vectors read from OUTCAR',
        action='store_true',
        default=False)
    args = parser.parse_args()

    if args.l_angular_momentum:
        args.orbitals = orbitals_with_l(args.l_angular_momentum)

    if args.xscaling:
        reciprocal_lattice = reciprocal_lattice_from_outcar(
            'OUTCAR')  # Move reading the reciprocal lattice to procar.py
    else:
        reciprocal_lattice = None

    pcar = procar.Procar()
    pcar.read_from_file(args.procar)
    pcar.print_weighted_band_structure(spins=args.spins,
                                       ions=args.ions,
                                       orbitals=args.orbitals,
                                       scaling=args.scaling,
                                       e_fermi=args.efermi,
                                       reciprocal_lattice=reciprocal_lattice)
Example #8
0
    def __init__(self, outcar_path, procar_path, ignore=0):
        r"""
        Initialises an instance of the :class:`~effmass.inputs.Data` class and checks data using :meth:`check_data`.

        Args:
            outcar_path (str): The path to the OUTCAR file
            procar_path (str): The path to the PROCAR file
            ignore (int): The number of kpoints to ignore at the beginning of the bandstructure slice through kspace (useful for hybrid calculations where zero weightings are appended to a previous self-consistent calculation).
        
        Returns: 
            None.
        """
        assert (type(outcar_path) == str), "The OUTCAR path must be a string"
        assert (type(procar_path) == str), "The PROCAR path must be a string"
        assert (type(ignore) == int and ignore >= 0
                ), "The number of kpoints to ignore must be a positive integer"

        reciprocal_lattice = outcar.reciprocal_lattice_from_outcar(outcar_path)
        vasp_data = procar.Procar()
        vasp_data.read_from_file(procar_path)

        self.spin_channels = vasp_data.spin_channels
        self.number_of_bands = vasp_data.number_of_bands
        self.number_of_ions = vasp_data.number_of_ions

        number_of_kpoints = vasp_data.number_of_k_points
        if vasp_data.calculation[
                'spin_polarised']:  # to account for the change in PROCAR format for calculations with 2 spin channels (1 k-point block ---> 2 k-point blocks)
            energies = np.zeros(
                [self.number_of_bands * 2, number_of_kpoints]
            )  # This is a very ugly way to slice 'n' dice. Should avoid creating new array and use array methods instead. But it does the job so will keep for now.
            for i in range(self.number_of_bands):
                energies[i] = vasp_data.bands[:, 1:].reshape(
                    number_of_kpoints * 2,  # factor or 2 for each kpoint block
                    self.number_of_bands).T[i][:number_of_kpoints]
                energies[self.number_of_bands +
                         i] = vasp_data.bands[:, 1:].reshape(
                             number_of_kpoints * 2,
                             self.number_of_bands).T[i][number_of_kpoints:]
            occupancy = np.zeros([self.number_of_bands * 2, number_of_kpoints])
            for i in range(self.number_of_bands):
                occupancy[i] = vasp_data.occupancy[:, 1:].reshape(
                    number_of_kpoints * 2,
                    self.number_of_bands).T[i][:number_of_kpoints]
                occupancy[self.number_of_bands +
                          i] = vasp_data.occupancy[:, 1:].reshape(
                              number_of_kpoints * 2,
                              self.number_of_bands).T[i][number_of_kpoints:]
        else:
            energies = vasp_data.bands[:, 1:].reshape(number_of_kpoints,
                                                      self.number_of_bands).T
            occupancy = vasp_data.occupancy[:, 1:].reshape(
                number_of_kpoints, self.number_of_bands).T

        # remove values which are from the self-consistent calculation prior to the bandstructure calculation (workflow for hybrid functionals)
        self.energies = np.delete(energies, list(range(ignore)), 1)
        self.occupancy = np.delete(occupancy, list(range(ignore)), 1)
        self.number_of_kpoints = number_of_kpoints - ignore

        self.kpoints = vasp_data.k_points[ignore:vasp_data.number_of_k_points]
        self.reciprocal_lattice = reciprocal_lattice * 2 * math.pi
        self.CBM = extrema._calc_CBM(self.occupancy, self.energies)
        self.VBM = extrema._calc_VBM(self.occupancy, self.energies)
        self.fermi_energy = (self.CBM + self.VBM) / 2
        self.dos = []
        self.integrated_dos = []
        self.check_data()
Example #9
0
    def main(self, energy_range=None, energy_depth=None):
        
        self.energy_range = energy_range * kt_to_ev
        self.energy_depth = energy_depth * kt_to_ev
        
        self.nocalcs = open('nocalc', 'w')
        self.reciprocal_lattice = (reciprocal_lattice_from_outcar('OUTCAR')
                              *2*math.pi)
        
        # Prepare output files
        column_headings = ( "# material " +
                            " theory " +
                            " energy_range " +
                            " energy_depth " +
                            " k_point " + 
                            " direction " + 
                            " band " + 
                            " occupancy " + 
                            " extrema_energy " +
                            " delta_k " + 
                            " delta_e " + 
                            " transport_mass " + 
                            " conductivity_mass " + 
                            " fit " +
                            " weight " +
                            " fit_kane " +
                            " explosion " +
                            "\n")
        
        with open("mass.txt","w") as file:
            file.write(column_headings)

        column_headings   = ( "# material" +
                              " theory " + 
                              " energy_range " +
                              " energy_depth " +
                              " k_point " + 
                              " direction " + 
                              " band " +
                              " occupancy " + 
                              " extrema_energy " +
                              " optical_mass " +
                              "\n")

        with open("average.txt","w") as file:
            file.write(column_headings)

            
        # Find energy extrema
        self.energy_extrema(self.energy_depth)
        
        # Calculate k_points to either side of extrema
        for band_index,k_point_index  in self.extrema_position: 
            k_point_indices = self.k_range(band_index, k_point_index,
                                           self.energy_range)
           
            # Effective mass for either side of extrema
            self.effective_mass( 
                    k_point_indices['above'], band_index)
            self.effective_mass( 
                    k_point_indices['below'], band_index)

        
        self.nocalcs.close()