Пример #1
0
 def test___add___spin_polarised_procars(self):
     pcar1 = procar.Procar()
     pcar2 = procar.Procar()
     with warnings.catch_warnings():
         warnings.simplefilter('ignore')
         pcar1._read_from_file(test_procar_spin_polarised_filename)
         pcar2._read_from_file(test_procar_spin_polarised_filename)
     combined_pcar = pcar1 + pcar2
     self.assertEqual(combined_pcar.spin_channels, 2)
     self.assertEqual(combined_pcar.number_of_ions, 25)
     self.assertEqual(combined_pcar.number_of_bands, 112)
     self.assertEqual(combined_pcar.number_of_k_points, 16)
Пример #2
0
 def test_read_from_file_warns_about_negative_occupancies(self):
     pcar = procar.Procar()
     with warnings.catch_warnings(record=True) as w:
         pcar.read_from_file(test_procar_filename,
                             negative_occupancies='warn')
         self.assertEqual(len(w), 1)
         self.assertTrue("negative" in str(w[-1].message))
Пример #3
0
 def test_read_from_file_zeros_occupancies_if_negative_occupancies_is_zero(
         self):
     pcar = procar.Procar()
     pcar.read_from_file(test_procar_filename, negative_occupancies='zero')
     np.testing.assert_array_equal(
         pcar.occupancy[:, 1],
         np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0]))
Пример #4
0
 def test_procar_occupation_values_are_read(self):
     pcar = procar.Procar()
     with warnings.catch_warnings():
         warnings.simplefilter('ignore')
         pcar.read_from_file(test_procar_filename)
         np.testing.assert_array_equal(
             pcar.occupancy[:, 1],
             np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -0.03191968]))
Пример #5
0
 def test_spin_polarised_procar_is_read_from_file(self):
     """Checking that `PROCAR_spin_polarised_test` is read"""
     pcar = procar.Procar()
     pcar.read_from_file(test_procar_spin_polarised_filename)
     self.assertEqual(pcar.spin_channels, 2)
     self.assertEqual(pcar.number_of_ions, 25)
     self.assertEqual(pcar.number_of_bands, 112)
     self.assertEqual(pcar.number_of_k_points, 8)
Пример #6
0
 def test___add___( self ):
     pcar1 = procar.Procar()
     pcar2 = procar.Procar()
     with warnings.catch_warnings():
         warnings.simplefilter('ignore')
         pcar1._read_from_file( test_procar_filename )
         pcar2._read_from_file( test_procar_filename )
     combined_pcar = pcar1 + pcar2
     self.assertEqual( combined_pcar.spin_channels, 4 )
     self.assertEqual( combined_pcar.number_of_ions, 22 )
     self.assertEqual( combined_pcar.number_of_bands, 4 )
     self.assertEqual( combined_pcar.number_of_k_points, 4 )
     expected_bands = np.ravel( np.concatenate( [ pcar1.bands,
                                                  pcar2.bands ], axis=1 ) )
     np.testing.assert_equal( combined_pcar._bands, expected_bands )
     for k1, k2 in zip( combined_pcar.k_points, pcar1.k_points + pcar2.k_points ):
         np.testing.assert_equal( k1.frac_coords, k2.frac_coords )
         self.assertEqual( k1.weight, k2.weight )
     self.assertEqual( [ k.index for k in combined_pcar.k_points ], [ 1, 2, 3, 4 ] )
Пример #7
0
 def test_procar_is_read_from_file(self):
     """Checking that `PROCAR_test` is read"""
     pcar = procar.Procar()
     with warnings.catch_warnings():
         warnings.simplefilter('ignore')
         pcar.read_from_file(test_procar_filename)
     self.assertEqual(pcar.spin_channels, 4)
     self.assertEqual(pcar.number_of_ions, 22)
     self.assertEqual(pcar.number_of_bands, 4)
     self.assertEqual(pcar.number_of_k_points, 2)
Пример #8
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)
Пример #9
0
 def test_procar_from_file_correctly_parses_bands(self):
     pcar = procar.Procar()
     with warnings.catch_warnings():
         warnings.simplefilter('ignore')
         pcar._read_from_file(test_procar_filename)
     np.testing.assert_equal([b.index for b in pcar._bands],
                             [1., 2., 3., 4., 1., 2., 3., 4.])
     np.testing.assert_equal([b.energy for b in pcar._bands], [
         -13.17934476, -13.17934476, -13.16936722, -13.16936722,
         -13.1849117, -13.1849117, -13.16621473, -13.16621472
     ])
     np.testing.assert_equal([b.occupancy for b in pcar._bands],
                             [1., 1., 1., 1., 1., 1., 1., -0.03191968])
Пример #10
0
 def test_procar_is_initialised( self ):
     pcar = procar.Procar()
     self.assertEqual( pcar.spin_channels, 1 )
     self.assertEqual( pcar.number_of_k_points, None )
     self.assertEqual( pcar.number_of_ions, None )
     self.assertEqual( pcar.number_of_bands, None )
     self.assertEqual( pcar.data, None )
     self.assertEqual( pcar.bands, None )
     self.assertEqual( pcar.occupancy, None )
     self.assertEqual( pcar.number_of_projections, None )
     self.assertEqual( pcar.k_point_blocks, None )
     self.assertEqual( pcar.calculation, { 'non_spin_polarised': False, 
                                           'non_collinear': False, 
                                           'spin_polarised': False } )
Пример #11
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()
Пример #12
0
 def setUp(self):
     self.procar = procar.Procar()
Пример #13
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)
Пример #14
0
 def test_read_from_file_if_negative_occupancies_is_ignore(self):
     pcar = procar.Procar()
     pcar.read_from_file(test_procar_filename,
                         negative_occupancies='ignore')
Пример #15
0
 def test_read_from_file_raises_exception_if_negative_occupancies_is_raise(
         self):
     pcar = procar.Procar()
     with self.assertRaises(ValueError):
         pcar.read_from_file(test_procar_filename,
                             negative_occupancies='raise')
Пример #16
0
 def test_read_from_file_raises_valueerror_if_negative_occupancies_is_invalid(
         self):
     pcar = procar.Procar()
     with self.assertRaises(ValueError):
         pcar.read_from_file(test_procar_filename,
                             negative_occupancies='foo')
Пример #17
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

        # 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 = 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()
Пример #18
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 )