Example #1
0
 def test_skparplot(self):
     """Can we plot a band-structure objectives?"""
     env = {}
     database = Database()
     latticeinfo = {'type': 'FCC', 'param': 5.4315}
     model = 'Si.bs'
     filename = '_workdir/test_plot/bs1.pdf'
     get_bandstructure(env,
                       database,
                       'test_dftbutils/Si/bs/',
                       model,
                       latticeinfo=latticeinfo)
     modeldb = database.get(model)
     bands = modeldb['bands']
     eps = 0.25
     jitter = eps * (0.5 - random(bands.shape))
     altbands = bands + jitter
     if os.path.exists(filename):
         os.remove(filename)
     else:
         os.makedirs('_workdir/test_plot', exist_ok=True)
     skparplot(modeldb['kvector'], [altbands, bands],
               filename=filename,
               xticklabels=modeldb['kticklabels'],
               xlabel='wave-vector',
               ylabel='Energy, eV',
               linelabels=['ref', 'model'],
               ylim=(-13, 6))
     self.assertTrue(os.path.exists(filename))
Example #2
0
 def test_get_special_Ek_options(self):
     """Get E(k) for explicitly given, and multiple bands"""
     env = {}
     database = Database()
     model = 'test.Ek'
     src = 'test_dftbutils/Si/bs'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     get_special_Ek(env,
                    database,
                    model,
                    model,
                    sympts=['K', 'L'],
                    extract={
                        'cb': [0, 2, 4, 6],
                        'vb': [0, 2, 4, 6]
                    })
     self.assertAlmostEqual(dst['Ec_L_4'], 2.8089, places=3)
     self.assertAlmostEqual(dst['Ec_L_0'], 0.3995, places=3)
     self.assertAlmostEqual(dst['Ec_K_0'], 0.6915, places=3)
     #
     self.assertAlmostEqual(dst['Ev_L_0'], -2.5016, places=3)
     self.assertAlmostEqual(dst['Ev_L_4'], -7.842, places=3)
     self.assertAlmostEqual(dst['Ev_L_6'], -11.3369, places=3)
     self.assertAlmostEqual(dst['Ev_K_0'], -3.5884, places=3)
     self.assertAlmostEqual(dst['Ev_K_2'], -4.963, places=3)
     self.assertAlmostEqual(dst['Ev_K_4'], -8.694, places=3)
     self.assertAlmostEqual(dst['Ev_K_6'], -9.8759, places=3)
Example #3
0
 def test_get_special_Ek(self):
     """Get E(k) for k obtained from the kLines"""
     env = {}
     database = Database()
     model = 'test.Ek'
     src = 'test_dftbutils/Si/bs'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     get_special_Ek(env, database, model, model)
     self.assertAlmostEqual(dst['Ec_L_0'], 0.4, places=3)
     self.assertAlmostEqual(dst['Ec_G_0'], 1.616, places=3)
     self.assertAlmostEqual(dst['Ec_X_0'], 0.2025, places=3)
     self.assertAlmostEqual(dst['Ec_U_0'], 0.6915, places=3)
     self.assertAlmostEqual(dst['Ec_K_0'], 0.6915, places=3)
     #
     self.assertAlmostEqual(dst['Ev_L_0'], -2.5016, places=3)
     self.assertAlmostEqual(dst['Ev_G_0'], -1.1289, places=3)
     self.assertAlmostEqual(dst['Ev_X_0'], -3.9592, places=3)
     self.assertAlmostEqual(dst['Ev_U_0'], -3.5885, places=3)
     self.assertAlmostEqual(dst['Ev_K_0'], -3.5885, places=3)
Example #4
0
 def test_get_bandstructure(self):
     """Can we get the bandstructure and gap/cb/vb details?"""
     env = {}
     database = Database()
     src = 'test_dftbutils/bs'
     dst = 'test.bs'
     get_bandstructure(env, database, src, dst)
     modeldict = database.get(dst)
     nptest.assert_array_almost_equal(modeldict['bands'], self.ref_bands)
     self.assertEqual(modeldict['nkpts'], self.ref_nk)
     self.assertEqual(modeldict['nbands'], self.ref_nb)
     self.assertEqual(modeldict['Ef'], self.ref_Ef)
     self.assertEqual(modeldict['Egap'], self.ref_Eg)
     self.assertEqual(modeldict['Ecb'], self.ref_Ec)
     self.assertEqual(modeldict['Evb'], self.ref_Ev)
Example #5
0
 def test_get_kvec_abscissa2(self):
     """Can we get the bandstructure and extract the kvector info"""
     latticeinfo = {'type': 'FCC', 'param': 1.}
     lat = Lattice(latticeinfo)
     database = Database()
     src = 'test_dftbutils/bs'
     get_bandstructure({'workroot': '.'}, database, src, 'test', latticeinfo=latticeinfo)
     kLines = database.get_item('test', 'kLines')
     bands = database.get_item('test', 'bands')
     logger.debug('Bands.shape: {}'.format(bands.shape))
     logger.debug('kLines     : {}'.format(kLines))
     xx, xt, xl = get_kvec_abscissa(lat, kLines)
     refxl = ['X', 'Γ', 'K', 'L', 'Γ']
     refxt = [0, 6.28319, 12.94751, 16.79516, 22.23656]
     self.assertListEqual(xl, refxl)
     nptest.assert_almost_equal(xt, refxt, 5)
     self.assertAlmostEqual(xx[-1], xt[-1])
     self.assertEqual(len(xx), kLines[-1][-1]+1)
Example #6
0
 def test_get_effmasses_default(self):
     """Can we get effective masses in addition to band-structure, with default settings?"""
     env = {}
     database = Database()
     src = 'test_dftbutils/Si/bs'
     model = 'test.meff'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     # the values below are in oldskpar.debug.log in the above dir
     self.assertTrue(dst['withSOC'])
     self.assertEqual(dst['ivbtop'], 7)
     self.assertEqual(dst['nkpts'], 206)
     self.assertEqual(dst['nbands'], 36)
     self.assertAlmostEqual(dst['Ef'], -3.0621, places=3)
     self.assertAlmostEqual(dst['Egap'], 1.1289, places=3)
     self.assertAlmostEqual(dst['Ecb'], -3.06221, places=3)
     self.assertAlmostEqual(dst['Evb'], -4.19099, places=3)
     #
     ref_klines = [('L', 0), ('Gamma', 53), ('X', 113), ('U', 141),
                   ('K', 142), ('Gamma', 205)]
     ref_klinesdict = {
         'K': [142],
         'X': [113],
         'Gamma': [53, 205],
         'L': [0],
         'U': [141]
     }
     self.assertListEqual(dst['kLines'], ref_klines)
     self.assertDictEqual(dst['kLinesDict'], ref_klinesdict)
     get_effmasses(env, database, model, model)
     ref_meff_tags = ['me_LG', 'me_GX', 'me_XU', 'me_KG']
     ref_meff_tags.extend(['mh_LG', 'mh_GX', 'mh_XU', 'mh_KG'])
     self.assertTrue(all([key in dst for key in ref_meff_tags]))
Example #7
0
def main_bands(args):
    """
    Chain the relevant tasks for obtaining band-structure and execute.
    """
    # setup logger
    # -------------------------------------------------------------------
    loglevel = logging.DEBUG if args.verbose else logging.INFO
    logger = get_logger(name='dftbutils',
                        filename='dftbutils.bands.log',
                        verbosity=loglevel)

    #logger.info(args)
    # deal with bands-specific arguments if any
    # --------------------------------------------------
    workroot = '.'
    workdir = abspath(expanduser(args.workdir))
    sccdir = abspath(joinpath(workdir, 'scc'))
    sccchg = abspath(joinpath(sccdir, 'charges.bin'))
    bsdir = abspath(joinpath(workdir, 'bs'))
    dftb = args.dftb
    dftblog = 'dftb.log'
    bands = args.bands
    if args.dos:
        dos = args.dos
    bandslog = 'dp_bands.log'

    if not args.plot_only:
        # Execute the necessary commands
        # scc calculation
        execute(cmd=dftb, workdir=sccdir, outfile=dftblog)
        # check log
        execute(cmd=['check_dftblog', dftblog],
                workdir=sccdir,
                outfile='chk.log')
        # extract dos for plotting
        if args.dos:
            execute(cmd=[dos, 'band.out', 'dos_total.dat'],
                    workdir=sccdir,
                    outfile=bandslog)
        # copy charges for klines calculation
        execute(cmd=['cp', '-f', sccchg, bsdir], workdir='.', outfile=None)
        # klines calculation
        execute(cmd=dftb, workdir=bsdir, outfile=dftblog)
        # check log
        execute(cmd=['check_dftblog', dftblog],
                workdir=sccdir,
                outfile='chk.log')
        # extract bands for plotting
        execute(cmd=[bands, 'band.out', 'bands'],
                workdir=bsdir,
                outfile=bandslog)

    if args.plot or args.plot_only:
        # hack the plotting directly, not via tasks, to avoid needing objectives
        database = {}
        implargs = {'workroot': workroot}
        get_bandstructure(implargs,
                          database,
                          bsdir,
                          'dftb',
                          latticeinfo=args.latticeinfo)
        bsdata = database.get('dftb')
        logger.info('Band-gap (eV) = {:.3f}'.format(bsdata['Egap']))
        yy1 = bsdata['bands'] - bsdata['Evb']
        if args.latticeinfo:
            xx1 = bsdata['kvector']
            xtl = bsdata['kticklabels']
        else:
            xx1 = np.asarray(range(yy1.shape[1]))
            xtl = None
        filename = os.path.join(workroot, workdir, 'bs.pdf')
        plot_bs(xx1, yy1, filename=filename, ylim=args.ylim, xticklabels=xtl)
Example #8
0
 def test_get_effmasses_select(self):
     """Can we get select effective masses with a control options?"""
     env = {}
     database = Database()
     model = 'test.meff'
     # NOTABENE: the refdata here is from SOC calculation!!!
     src = 'test_dftbutils/Si/bs'
     get_bandstructure(env,
                       database,
                       src,
                       model,
                       latticeinfo={
                           'type': 'FCC',
                           'param': 5.431
                       })
     dst = database.get(model)
     directions = ['Gamma-X', 'Gamma-L', 'Gamma-K']
     # Example how to extract different masses over a different energy window:
     # Note that subsequent extractions overwrite final data in dst, so we start with
     # the deepest bands, and than reduce the number of bands, towards to top of VB
     # The energy window should be adjusted depending on the anticipated curvature of the band
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='e',
                   nb=1,
                   Erange=0.005,
                   usebandindex=True)
     # get the lowest band masses: (spin-orbit); forceErange seems to not work properly?
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='h',
                   nb=5,
                   Erange=0.0015,
                   forceErange=True)
     # get the light hole bands (3 and 4)
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='h',
                   nb=3,
                   Erange=0.008)
     # get the top two (heavy hole) bands (1 and 2); enforce indexing! (i.e. add _0)
     get_effmasses(env,
                   database,
                   model,
                   model,
                   directions=directions,
                   carriers='h',
                   nb=1,
                   Erange=0.002,
                   usebandindex=True)
     self.assertAlmostEqual(dst['me_GX_0'], 0.935, places=3)
     self.assertAlmostEqual(dst['mh_GX_0'], -0.278, places=2)
     self.assertAlmostEqual(dst['mh_GK_0'], -1.891, places=3)
     self.assertAlmostEqual(dst['mh_GL_0'], -0.633, places=3)
     self.assertAlmostEqual(dst['mh_GX_2'], -0.286, places=3)
     self.assertAlmostEqual(dst['mh_GK_2'], -0.362, places=3)
     self.assertAlmostEqual(dst['mh_GL_2'], -2.2426, places=3)
     self.assertAlmostEqual(dst['mh_GX_4'], -0.1389, places=3)
     self.assertAlmostEqual(dst['mh_GK_4'], -0.095, places=3)
     self.assertAlmostEqual(dst['mh_GL_4'], -0.086, places=3)
     self.assertAlmostEqual(dst['cbminpos_GX_0'], 0.817, places=2)