Esempio n. 1
0
def boltz_run(vrun=""):
    """
  Helper function to run and store Bolztrap 
  Please note high denske k-point mesh is needed
  The automatic k-point convergene in JARVIS-DFT is generally good enough
  
  Args:
      vrun: path to vasprun.xml
  Returns:
        BoltztrapAnalyzer object
  """
    if which("x_trans") is None or which("BoltzTraP") is None:
        print("Please install BoltzTrap")
    v = Vasprun(vrun)
    kp = vrun.replace("vasprun.xml", "KPOINTS")
    out = vrun.replace("vasprun.xml", "OUTCAR")
    for line in open(out, "r"):
        if "NELECT" in line:
            nelect = float(line.split()[2])
    bs = v.get_band_structure(kp, line_mode=False)
    brun = BoltztrapRunner(bs, nelect)
    path = vrun.split("vasprun.xml")[0]
    folder = str(path) + str("/boltztrap")
    out_trans = str(folder) + str("/boltztrap.outputtrans")
    if not os.path.exists(out_trans):
        brun.run(path_dir=path)
        print("doesnt exist", out_trans)
    bana = BoltztrapAnalyzer.from_files(folder)
    return bana
Esempio n. 2
0
    def process_item(self, item):
        """
        Calculates dos running Boltztrap in DOS run mode

        Args:
            item (dict): a dict with a material_id, bs and a structure

        Returns:
            cdos: a complete dos object
        """
        self.logger.debug("Calculating Boltztrap for {}".format(
            item[self.materials.key]))

        nelect = item["input"]["parameters"]["NELECT"]

        bs_dict = item["uniform_bandstructure"]["bs"]
        bs_dict['structure'] = item['structure']
        bs = BandStructure.from_dict(bs_dict)

        with ScratchDir("."):
            if bs.is_spin_polarized:
                run_path = os.path.join(os.getcwd(), "dos_up")
                makedirs_p(run_path)
                BoltztrapRunner(bs=bs,
                                nelec=nelect,
                                run_type="DOS",
                                dos_type="TETRA",
                                spin=1).run(path_dir=run_path)
                btrap_dir = os.path.join(run_path, "boltztrap")
                bta_up = BoltztrapAnalyzer.from_files(btrap_dir)

                run_path = os.path.join(os.getcwd(), "dos_dw")
                makedirs_p(run_path)
                BoltztrapRunner(bs=bs,
                                nelec=nelect,
                                run_type="DOS",
                                dos_type="TETRA",
                                spin=-1).run(path_dir=run_path)
                btrap_dir = os.path.join(run_path, "boltztrap")
                bta_dw = BoltztrapAnalyzer.from_files(btrap_dir)

                cdos = an_up.get_complete_dos(bs.structure, an_dw)

            else:
                run_path = os.path.join(os.getcwd(), "dos")
                makedirs_p(run_path)
                BoltztrapRunner(bs=bs,
                                nelec=nelect,
                                run_type="DOS",
                                dos_type="TETRA").run(path_dir=run_path)
                btrap_dir = os.path.join(run_path, "boltztrap")
                bta = BoltztrapAnalyzer.from_files(btrap_dir)

                cdos = an.get_complete_dos(bs.structure)

        return {'cdos': cdos.as_dict()}
Esempio n. 3
0
    def run_task(self, fw_spec):
        scissor = self.get("scissor", 0.0)
        tmax = self.get("tmax", 1300)
        tgrid = self.get("tgrid", 50)
        doping = self.get("doping", None)
        soc = self.get("soc", False)

        vasprun, outcar = get_vasprun_outcar(".", parse_dos=True, parse_eigen=True)
        bs = vasprun.get_band_structure()
        nelect = outcar.nelect
        runner = BoltztrapRunner(bs, nelect, scissor=scissor, doping=doping, tmax=tmax, tgrid=tgrid, soc=soc)
        runner.run(path_dir=os.getcwd())
Esempio n. 4
0
    def run_task(self, fw_spec):
        scissor = self.get("scissor", 0.0)
        tmax = self.get("tmax", 1300)
        tgrid = self.get("tgrid", 50)
        doping = self.get("doping", None)
        soc = self.get("soc", False)

        vasprun, outcar = get_vasprun_outcar(".", parse_dos=True, parse_eigen=True)
        bs = vasprun.get_band_structure()
        nelect = outcar.nelect
        runner = BoltztrapRunner(bs, nelect, scissor=scissor, doping=doping, tmax=tmax,
                                 tgrid=tgrid, soc=soc)

        runner.run(path_dir=os.getcwd())
Esempio n. 5
0
    def process_item(self, item):
        """
        Calculates diffraction patterns for the structures

        Args:
            item (dict): a dict with a material_id and a structure

        Returns:
            dict: a diffraction dict
        """
        self.logger.debug("Calculating Boltztrap for {}".format(
            item[self.materials.key]))

        nelect = item["input"]["parameters"]["NELECT"]

        bs_dict = item["uniform_bandstructure"]["bs"]
        bs_dict['structure'] = item['structure']
        bs = BandStructure.from_dict(bs_dict)

        with ScratchDir("."):
            BoltztrapRunner(bs=bs, nelec=nelect).run(path_dir=os.getcwd())
            btrap_dir = os.path.join(os.getcwd(), "boltztrap")
            bta = BoltztrapAnalyzer.from_files(btrap_dir)

        d = {
            "bta": bta.as_dict(),
            "boltztrap": {
                "thermoelectric": bt_analysis_thermoelectric(bta),
                "tcm": bt_analysis_tcm(bta)
            }
        }

        return d
Esempio n. 6
0
    def setUp(self):
        self.bz = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/transp/"))
        self.bz_bands = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/bands/"))
        self.bz_up = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/dos_up/"), dos_spin=1)
        self.bz_dw = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/dos_dw/"), dos_spin=-1)
        self.bz_fermi = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/fermi/"))

        with open(os.path.join(test_dir, "Cu2O_361_bandstructure.json"), "rt") as f:
            d = json.load(f)
            self.bs = BandStructure.from_dict(d)
            self.btr = BoltztrapRunner(self.bs, 1)
    def get_interpolated_dos(self, mat):

        nelect = mat["calc_settings"]["nelect"]

        bs_dict = mat["bandstructure"]["uniform_bs"]
        bs_dict["structure"] = mat['structure']
        bs = BandStructure.from_dict(bs_dict)

        if bs.is_spin_polarized:
            with ScratchDir("."):
                BoltztrapRunner(bs=bs,
                                nelec=nelect,
                                run_type="DOS",
                                dos_type="TETRA",
                                spin=1,
                                timeout=60).run(path_dir=os.getcwd())
                an_up = BoltztrapAnalyzer.from_files("boltztrap/", dos_spin=1)

            with ScratchDir("."):
                BoltztrapRunner(bs=bs,
                                nelec=nelect,
                                run_type="DOS",
                                dos_type="TETRA",
                                spin=-1,
                                timeout=60).run(path_dir=os.getcwd())
                an_dw = BoltztrapAnalyzer.from_files("boltztrap/", dos_spin=-1)

            cdos = an_up.get_complete_dos(bs.structure, an_dw)

        else:
            with ScratchDir("."):
                BoltztrapRunner(bs=bs,
                                nelec=nelect,
                                run_type="DOS",
                                dos_type="TETRA",
                                timeout=60).run(path_dir=os.getcwd())
                an = BoltztrapAnalyzer.from_files("boltztrap/")
            cdos = an.get_complete_dos(bs.structure)

        return cdos
Esempio n. 8
0
    def setUpClass(cls):
        cls.bz = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/transp/"))
        cls.bz_bands = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/bands/"))
        cls.bz_up = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/dos_up/"), dos_spin=1)
        cls.bz_dw = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/dos_dw/"), dos_spin=-1)
        cls.bz_fermi = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/fermi/"))

        with open(os.path.join(test_dir, "Cu2O_361_bandstructure.json"),
                  "rt") as f:
            d = json.load(f)
            cls.bs = BandStructure.from_dict(d)
            cls.btr = BoltztrapRunner(cls.bs, 1)
        warnings.simplefilter("ignore")
Esempio n. 9
0
def boltztrap(tmax=1001,
              tstep=50,
              doping=np.logspace(18, 21, 17),
              vasprun='vasprun.xml',
              zero_weighted=False,
              kpoints=None,
              relaxation_time=1e-14,
              run=True,
              analyse=True,
              output='boltztrap.hdf5',
              **kwargs):
    """Runs BoltzTraP

    Runs quicker than the pymatgen from_files version.
    Also writes to a hdf5 file.
    Minimum temperature is 200 K or tstep, whichever is larger.
    Note: BoltzTraP can be a fickle friend, so if you're getting errors,
    it may be worth reinstalling or trying on a different machine.
    Testing with a small number of temperature/ doping combinations is also
    recommended.

    Arguments
    ---------

        tmax : float, optional
            maximum temperature in K. Default: 1000.
        tstep : float, optional
            temperature step in K. Default: 10.
        doping : array-like, optional
            doping concentrations in cm-1. Default: np.logspace(18, 21, 101).

        vasprun : str, optional
            path to vasprun. Default: vasprun.xml.
        zero_weighted : bool, optional
            zero weighted kpoints used. Default: False.
        kpoints : str, optional
            path to KPOINTS file if zero_weighted. Default: KPOINTS.
        relaxation_time : float, optional
            charge carrier relaxation time. Default: 1e-14.

        run : bool, optional
            run BoltzTraP. Default: True.
        analyse : bool, optional
            analyse BoltzTraP. Default: True.
        output : str, optional
            output hdf5 filename. Default: boltztrap.hdf5.

        **kwargs
            passed to pymatgen.electronic.structure.boltztrap.BoltztrapRunner.
            Recommended arguments include:

                soc : bool, optional
                    spin orbit coupling. Default: False.
                lpfac : int, optional
                    interpolation factor. Default: 10.
                timeout : float, optional
                    Convergence time limit in seconds. Default: 7200.
    """

    import h5py
    import os
    from pymatgen.electronic_structure.boltztrap import BoltztrapRunner, BoltztrapAnalyzer
    from pymatgen.io.vasp.outputs import Vasprun
    from scipy import constants

    # check inputs

    for name, value in zip(['zero_weighted', 'run', 'analyse'],
                           [zero_weighted, run, analyse]):
        assert isinstance(value, bool), '{} must be True or False'.format(name)

    tmax += tstep
    tmin = 200
    if tstep > tmin:
        tmin = tstep
    temperature = np.arange(tmin, tmax, tstep)

    if run:  # run boltztrap from vasprun.xml -> boltztrap directory
        doping = np.array(doping)
        vr = Vasprun(vasprun)
        bs = vr.get_band_structure(line_mode=zero_weighted,
                                   kpoints_filename=kpoints)
        nelect = vr.parameters['NELECT']

        btr = BoltztrapRunner(bs,
                              nelect,
                              doping=list(doping),
                              tmax=tmax,
                              tgrid=tstep,
                              **kwargs)
        print('Running Boltztrap...', end='')
        btr_dir = btr.run(path_dir='.')
        print('Done.')
        """
        Detects whether the BoltzTraP build on this computer writes the
        doping concentrations correctly, and if it doesn't, writes them.
        """
        with open('boltztrap/boltztrap.outputtrans', 'r') as f:
            line = f.readlines()[-2]
        if len(line) >= 23 and line[:23] == ' Calling FermiIntegrals':
            with open(os.path.join(btr_dir, 'boltztrap.outputtrans'),
                      'a') as f:
                for i, x in enumerate(np.concatenate((doping, -doping))):
                    f.write(
                        'Doping level number {} n = {} carriers/cm3\n'.format(
                            i, x))

    else:
        btr_dir = 'boltztrap'

    if analyse:  # run boltztrap from boltztrap directory -> hdf5 file
        print('Analysing Boltztrap...', end='')
        bta = BoltztrapAnalyzer.from_files(btr_dir)
        print('Done.')

        data = {
            'average_eff_mass': {},
            'conductivity': {},
            'doping': doping,
            'power_factor': {},
            'seebeck': {},
            'temperature': temperature,
            'thermal_conductivity': {}
        }

        # load data

        print('Calculating transport...', end='')
        c = bta._cond_doping
        dp = bta.doping
        e = constants.e
        f = bta.mu_doping
        k = bta._kappa_doping
        me = constants.m_e
        s = bta._seebeck_doping

        # calculate transport properties

        for d in ['n', 'p']:
            c[d] = np.array([c[d][t] for t in temperature])
            dp[d] = np.array(dp[d])
            k[d] = np.array([k[d][t] for t in temperature])
            f[d] = np.array([f[d][t] for t in temperature])
            s[d] = np.array([s[d][t] for t in temperature])

            data['average_eff_mass'][d] = np.linalg.inv(c[d]) \
                                        * dp[d][None, :, None, None] \
                                        * 1e6 * e ** 2 / me
            data['conductivity'][d] = np.multiply(c[d], relaxation_time)
            data['seebeck'][d] = np.multiply(s[d], 1e6)
            data['power_factor'][d] = tp.calculate.power_factor(c[d], s[d])
            data['thermal_conductivity'][d] = (k[d] - s[d] ** 2 * c[d] \
                                            * temperature[:,None,None,None]) \
                                            * relaxation_time
        data['fermi_level'] = f
        print('Done.')

        tp.data.save.hdf5(data, output)

    return
Esempio n. 10
0
def boltztrap(tmax=1001,
              tstep=50,
              tmin=None,
              doping=np.logspace(18, 21, 17),
              ke_mode='boltzmann',
              vasprun='vasprun.xml',
              kpoints=None,
              relaxation_time=1e-14,
              lpfac=10,
              run=True,
              analyse=True,
              output='boltztrap.hdf5',
              **kwargs):
    """Runs BoltzTraP from a VASP density of states (DoS).

    Runs quicker and more robustly than the pymatgen from_files version,
    and outputs an hdf5 file.
    Note: BoltzTraP can be a fickle friend, so if you're getting errors,
    it may be worth reinstalling or trying on a different machine.

    Arguments
    ---------

        tmax : float, optional
            maximum temperature in K. Default: 1000.
        tstep : float, optional
            temperature step in K. Default: 50.
        tmin : float, optional
            minimum temperature in K. This does not reduce how many
            temperatures are run in BoltzTraP, only how many are saved
            to hdf5. Default: tstep.
        doping : array-like, optional
            doping concentrations in cm-1.
            Default: np.logspace(18, 21, 17).
        k_mode : str, optional
            method for calculating the electronic thermal conductivity.
            Options:

                boltzmann (default):
                    standard boltztrap method. Madsen and Singh,
                    Comput. Phys. Commun. 2006, 175, 67.
                wiedemann:
                    Wiedemann-Franz law with constant L = 2.44E-8.
                    Franz and Wiedemann, Ann. Phys. 1853, 165, 497.
                snyder:
                    Wiedemann-Franz law, with L varying with Seebeck.
                    Kim et al., APL Mat. 2015, 3, 041506.

        vasprun : str, optional
            path to vasprun. Default: vasprun.xml.
        kpoints : str, optional
            path to KPOINTS file if there are zero-weighted k-points.
            Default: KPOINTS.
        relaxation_time : float, optional
            charge carrier relaxation time. Default: 1e-14.
        lpfac : int, optional
            DoS interpolation factor. Default: 10.

        run : bool, optional
            run BoltzTraP. Default: True.
        analyse : bool, optional
            analyse BoltzTraP. Default: True.
        output : str, optional
            output hdf5 filename. Default: boltztrap.hdf5.

        kwargs
            passed to pymatgen.electronic.structure.boltztrap.BoltztrapRunner.

    Returns
    -------

        None
            instead prints to hdf5 (see below).

    hdf5 File Contents
    ------------------

        average_eff_mass : dict
            the charge carrier effective mass in units of m_e, taking
            into account all bands, as opposed to the single parabolic
            band model.
            Data is a dictionary with an array each for n and p doping,
            of shape (temperatures, concentrations, 3, 3).
        conductivity : dict
            electric conductivity in S m-1.
            Data is a dictionary with an array each for n and p doping,
            of shape (temperatures, concentrations, 3, 3).
        doping : array-like
            carrier concentration in cm-1. Identical to input.
        electronic_thermal_conductivity : dict
            electronic thermal conductivity in W m-1 K-1.
            Data is a dictionary with an array each for n and p doping,
            of shape (temperatures, concentrations, 3, 3).
        fermi_level : dict
            fermi level at different temperatures in units of eV.
            Data is a dictionary with an array each for n and p doping,
            of shape (temperatures, concentrations).
        power_factor : dict
            power factor in W m-1 K-2.
            Data is a dictionary with an array each for n and p doping,
            of shape (temperatures, concentrations, 3, 3).
        seebeck : dict
            Seebeck coefficient in muV K-1.
            Data is a dictionary with an array each for n and p doping,
            of shape (temperatures, concentrations, 3, 3).
        temperature : numpy array
            temperatures in K.
        meta : dict
            metadata:

                interpolation_factor : int
                    lpfac.
                ke_mode : str
                    as input.
                relaxation_time : float
                    as input.
                soc : bool
                    spin-orbit coupling calculation.
                units : dict
                    units of each property above.
    """

    import h5py
    import os
    from pymatgen.electronic_structure.boltztrap \
         import BoltztrapRunner, BoltztrapAnalyzer, BoltztrapError
    from pymatgen.io.vasp.outputs import Vasprun
    from scipy import constants

    # check inputs

    for name, value in zip(['run', 'analyse'], [run, analyse]):
        assert isinstance(value, bool), '{} must be True or False'.format(name)

    ke_mode = ke_mode.lower()
    ke_modes = ['boltzmann', 'wiedemann', 'snyder']
    assert ke_mode in ke_modes, 'ke_mode must be {} or {}.'.format(
        ', '.join(ke_modes[:-1]), ke_modes[-1])

    tmax += tstep
    tmin = tstep if tmin is None else tmin
    temperature = np.arange(tmin, tmax, tstep)

    if run:  # run boltztrap from vasprun.xml -> boltztrap directory
        doping = np.array(doping)
        vr = Vasprun(vasprun, parse_potcar_file=False)
        soc = vr.as_dict()['input']['parameters']['LSORBIT']
        try:
            bs = vr.get_band_structure(line_mode=False)
            nelect = vr.parameters['NELECT']
            btr = BoltztrapRunner(bs,
                                  nelect,
                                  doping=list(doping),
                                  tmax=tmax,
                                  tgrid=tstep,
                                  soc=soc,
                                  lpfac=lpfac,
                                  **kwargs)
            print('Running Boltztrap...', end='')
            btr_dir = btr.run(path_dir='.')
            print('Done.')
        except BoltztrapError:
            bs = vr.get_band_structure(line_mode=True,
                                       kpoints_filename=kpoints)
            nelect = vr.parameters['NELECT']
            btr = BoltztrapRunner(bs,
                                  nelect,
                                  doping=list(doping),
                                  tmax=tmax,
                                  tgrid=tstep,
                                  soc=soc,
                                  lpfac=lpfac,
                                  **kwargs)
            btr_dir = btr.run(path_dir='.')
            print('Done.')
        """
        Detects whether the BoltzTraP build on this computer writes the
        doping concentrations correctly, and if it doesn't, writes them.
        """
        with open('boltztrap/boltztrap.outputtrans', 'r') as f:
            line = f.readlines()[-2]
        if len(line) >= 23 and line[:23] == ' Calling FermiIntegrals':
            with open(os.path.join(btr_dir, 'boltztrap.outputtrans'),
                      'a') as f:
                for i, x in enumerate(np.concatenate((doping, -doping))):
                    f.write(
                        'Doping level number {} n = {} carriers/cm3\n'.format(
                            i, x))

    else:
        btr_dir = 'boltztrap'

    if analyse:  # run boltztrap from boltztrap directory -> hdf5 file
        print('Analysing Boltztrap...', end='')
        bta = BoltztrapAnalyzer.from_files(btr_dir)
        print('Done.')

        data = {
            'average_eff_mass': {},
            'conductivity': {},
            'doping': doping,
            'electronic_thermal_conductivity': {},
            'power_factor': {},
            'seebeck': {},
            'temperature': temperature,
            'meta': {
                'units': {
                    'average_eff_mass': 'm_e',
                    'conductivity': 'S m-1',
                    'doping': 'cm-1',
                    'electronic_thermal_conductivity': 'W m-1 K-1',
                    'fermi_level': 'eV',
                    'power_factor': 'W m-1 K-2',
                    'seebeck': 'muV K-1',
                    'temperature': 'K'
                },
                'interpolation_factor': lpfac,
                'ke_mode': ke_mode,
                'relaxation_time': relaxation_time,
                'soc': soc
            }
        }

        # load data

        print('Calculating transport...', end='')
        c = bta._cond_doping
        dp = bta.doping
        e = constants.e
        f = bta.mu_doping
        k = bta._kappa_doping
        me = constants.m_e
        s = bta._seebeck_doping

        # calculate transport properties

        for d in ['n', 'p']:
            c[d] = np.array([c[d][t] for t in temperature])
            dp[d] = np.array(dp[d])
            k[d] = np.array([k[d][t] for t in temperature])
            f[d] = np.array([f[d][t] for t in temperature])
            s[d] = np.array([s[d][t] for t in temperature])

            data['average_eff_mass'][d] = np.linalg.inv(c[d]) \
                                        * dp[d][None, :, None, None] \
                                        * 1e6 * e ** 2 / me
            data['conductivity'][d] = np.multiply(c[d], relaxation_time)
            data['seebeck'][d] = np.multiply(s[d], 1e6)
            data['power_factor'][d] = tp.calculate.power_factor(
                data['conductivity'][d], data['seebeck'][d])
            if ke_mode == 'boltztrap':
                data['electronic_thermal_conductivity'][d] = \
                      k[d] * relaxation_time \
                      - data['power_factor'][d] * temperature[:,None,None,None]
            else:
                if ke_mode == 'wiedemann':
                    L = 2.44E-8
                else:
                    L = (1.5 +
                         np.exp(-np.abs(data['seebeck'][d]) / 116)) * 1e-8
                data['electronic_thermal_conductivity'][d] = \
                    L * data['conductivity'][d] * temperature[:,None,None,None]

        data['fermi_level'] = f
        print('Done.')

        tp.data.save.hdf5(data, output)

    return
Esempio n. 11
0
    def run_task(self, fw_spec):
        # import here to prevent import errors in bigger MPCollab
        # get the band structure and nelect from files
        """
        prev_dir = get_loc(fw_spec['prev_vasp_dir'])
        vasprun_loc = zpath(os.path.join(prev_dir, 'vasprun.xml'))
        kpoints_loc = zpath(os.path.join(prev_dir, 'KPOINTS'))

        vr = Vasprun(vasprun_loc)
        bs = vr.get_band_structure(kpoints_filename=kpoints_loc)
        """
        filename = get_slug(
            'JOB--' + fw_spec['mpsnl'].structure.composition.reduced_formula +
            '--' + fw_spec['task_type'])
        with open(filename, 'w+') as f:
            f.write('')

        # get the band structure and nelect from DB
        block_part = get_block_part(fw_spec['prev_vasp_dir'])

        db_dir = os.environ['DB_LOC']
        assert isinstance(db_dir, object)
        db_path = os.path.join(db_dir, 'tasks_db.json')
        with open(db_path) as f:
            creds = json.load(f)
            connection = MongoClient(creds['host'], creds['port'])
            tdb = connection[creds['database']]
            tdb.authenticate(creds['admin_user'], creds['admin_password'])

            props = {
                "calculations": 1,
                "task_id": 1,
                "state": 1,
                "pseudo_potential": 1,
                "run_type": 1,
                "is_hubbard": 1,
                "hubbards": 1,
                "unit_cell_formula": 1
            }
            m_task = tdb.tasks.find_one({"dir_name": block_part}, props)
            if not m_task:
                time.sleep(
                    60)  # only thing to think of is wait for DB insertion(?)
                m_task = tdb.tasks.find_one({"dir_name": block_part}, props)

            if not m_task:
                raise ValueError(
                    "Could not find task with dir_name: {}".format(block_part))

            if m_task['state'] != 'successful':
                raise ValueError(
                    "Cannot run Boltztrap; parent job unsuccessful")

            nelect = m_task['calculations'][0]['input']['parameters']['NELECT']
            bs_id = m_task['calculations'][0]['band_structure_fs_id']
            print bs_id, type(bs_id)
            fs = gridfs.GridFS(tdb, 'band_structure_fs')
            bs_dict = json.loads(fs.get(bs_id).read())
            bs_dict['structure'] = m_task['calculations'][0]['output'][
                'crystal']
            bs = BandStructure.from_dict(bs_dict)
            print("find previous run with block_part {}".format(block_part))
            print 'Band Structure found:', bool(bs)
            print(bs.as_dict())
            print("nelect: {}".format(nelect))

            # run Boltztrap
            doping = []
            for d in [1e16, 1e17, 1e18, 1e19, 1e20]:
                doping.extend([1 * d, 2.5 * d, 5 * d, 7.5 * d])
            doping.append(1e21)
            runner = BoltztrapRunner(bs, nelect, doping=doping)
            dir = runner.run(path_dir=os.getcwd())

            # put the data in the database
            bta = BoltztrapAnalyzer.from_files(dir)

            # 8/21/15 - Anubhav removed fs_id (also see line further below, ted['boltztrap_full_fs_id'] ...)
            # 8/21/15 - this is to save space in MongoDB, as well as non-use of full Boltztrap output (vs rerun)
            """
            data = bta.as_dict()
            data.update(get_meta_from_structure(bs._structure))
            data['snlgroup_id'] = fw_spec['snlgroup_id']
            data['run_tags'] = fw_spec['run_tags']
            data['snl'] = fw_spec['mpsnl']
            data['dir_name_full'] = dir
            data['dir_name'] = get_block_part(dir)
            data['task_id'] = m_task['task_id']
            del data['hall']  # remove because it is too large and not useful
            fs = gridfs.GridFS(tdb, "boltztrap_full_fs")
            btid = fs.put(json.dumps(jsanitize(data)))
            """

            # now for the "sanitized" data
            ted = bta.as_dict()
            del ted['seebeck']
            del ted['hall']
            del ted['kappa']
            del ted['cond']

            # ted['boltztrap_full_fs_id'] = btid
            ted['snlgroup_id'] = fw_spec['snlgroup_id']
            ted['run_tags'] = fw_spec['run_tags']
            ted['snl'] = fw_spec['mpsnl'].as_dict()
            ted['dir_name_full'] = dir
            ted['dir_name'] = get_block_part(dir)
            ted['task_id'] = m_task['task_id']

            ted['pf_doping'] = bta.get_power_factor(output='tensor',
                                                    relaxation_time=self.TAU)
            ted['zt_doping'] = bta.get_zt(output='tensor',
                                          relaxation_time=self.TAU,
                                          kl=self.KAPPAL)

            ted['pf_eigs'] = self.get_eigs(ted, 'pf_doping')
            ted['pf_best'] = self.get_extreme(ted, 'pf_eigs')
            ted['pf_best_dope18'] = self.get_extreme(ted,
                                                     'pf_eigs',
                                                     max_didx=3)
            ted['pf_best_dope19'] = self.get_extreme(ted,
                                                     'pf_eigs',
                                                     max_didx=4)
            ted['zt_eigs'] = self.get_eigs(ted, 'zt_doping')
            ted['zt_best'] = self.get_extreme(ted, 'zt_eigs')
            ted['zt_best_dope18'] = self.get_extreme(ted,
                                                     'zt_eigs',
                                                     max_didx=3)
            ted['zt_best_dope19'] = self.get_extreme(ted,
                                                     'zt_eigs',
                                                     max_didx=4)
            ted['seebeck_eigs'] = self.get_eigs(ted, 'seebeck_doping')
            ted['seebeck_best'] = self.get_extreme(ted, 'seebeck_eigs')
            ted['seebeck_best_dope18'] = self.get_extreme(ted,
                                                          'seebeck_eigs',
                                                          max_didx=3)
            ted['seebeck_best_dope19'] = self.get_extreme(ted,
                                                          'seebeck_eigs',
                                                          max_didx=4)
            ted['cond_eigs'] = self.get_eigs(ted, 'cond_doping')
            ted['cond_best'] = self.get_extreme(ted, 'cond_eigs')
            ted['cond_best_dope18'] = self.get_extreme(ted,
                                                       'cond_eigs',
                                                       max_didx=3)
            ted['cond_best_dope19'] = self.get_extreme(ted,
                                                       'cond_eigs',
                                                       max_didx=4)
            ted['kappa_eigs'] = self.get_eigs(ted, 'kappa_doping')
            ted['kappa_best'] = self.get_extreme(ted,
                                                 'kappa_eigs',
                                                 maximize=False)
            ted['kappa_best_dope18'] = self.get_extreme(ted,
                                                        'kappa_eigs',
                                                        maximize=False,
                                                        max_didx=3)
            ted['kappa_best_dope19'] = self.get_extreme(ted,
                                                        'kappa_eigs',
                                                        maximize=False,
                                                        max_didx=4)

            try:
                from mpcollab.thermoelectrics.boltztrap_TE import BoltzSPB
                bzspb = BoltzSPB(ted)
                maxpf_p = bzspb.get_maximum_power_factor(
                    'p',
                    temperature=0,
                    tau=1E-14,
                    ZT=False,
                    kappal=0.5,
                    otherprops=('get_seebeck_mu_eig',
                                'get_conductivity_mu_eig',
                                'get_thermal_conductivity_mu_eig',
                                'get_average_eff_mass_tensor_mu'))

                maxpf_n = bzspb.get_maximum_power_factor(
                    'n',
                    temperature=0,
                    tau=1E-14,
                    ZT=False,
                    kappal=0.5,
                    otherprops=('get_seebeck_mu_eig',
                                'get_conductivity_mu_eig',
                                'get_thermal_conductivity_mu_eig',
                                'get_average_eff_mass_tensor_mu'))

                maxzt_p = bzspb.get_maximum_power_factor(
                    'p',
                    temperature=0,
                    tau=1E-14,
                    ZT=True,
                    kappal=0.5,
                    otherprops=('get_seebeck_mu_eig',
                                'get_conductivity_mu_eig',
                                'get_thermal_conductivity_mu_eig',
                                'get_average_eff_mass_tensor_mu'))

                maxzt_n = bzspb.get_maximum_power_factor(
                    'n',
                    temperature=0,
                    tau=1E-14,
                    ZT=True,
                    kappal=0.5,
                    otherprops=('get_seebeck_mu_eig',
                                'get_conductivity_mu_eig',
                                'get_thermal_conductivity_mu_eig',
                                'get_average_eff_mass_tensor_mu'))

                ted['zt_best_finemesh'] = {'p': maxzt_p, 'n': maxzt_n}
                ted['pf_best_finemesh'] = {'p': maxpf_p, 'n': maxpf_n}
            except:
                import traceback
                traceback.print_exc()
                print 'COULD NOT GET FINE MESH DATA'

            # add is_compatible
            mpc = MaterialsProjectCompatibility("Advanced")
            try:
                func = m_task["pseudo_potential"]["functional"]
                labels = m_task["pseudo_potential"]["labels"]
                symbols = ["{} {}".format(func, label) for label in labels]
                parameters = {
                    "run_type": m_task["run_type"],
                    "is_hubbard": m_task["is_hubbard"],
                    "hubbards": m_task["hubbards"],
                    "potcar_symbols": symbols
                }
                entry = ComputedEntry(Composition(m_task["unit_cell_formula"]),
                                      0.0,
                                      0.0,
                                      parameters=parameters,
                                      entry_id=m_task["task_id"])

                ted["is_compatible"] = bool(mpc.process_entry(entry))
            except:
                traceback.print_exc()
                print 'ERROR in getting compatibility, task_id: {}'.format(
                    m_task["task_id"])
                ted["is_compatible"] = None

            tdb.boltztrap.insert(jsanitize(ted))

            update_spec = {
                'prev_vasp_dir': fw_spec['prev_vasp_dir'],
                'boltztrap_dir': os.getcwd(),
                'prev_task_type': fw_spec['task_type'],
                'mpsnl': fw_spec['mpsnl'].as_dict(),
                'snlgroup_id': fw_spec['snlgroup_id'],
                'run_tags': fw_spec['run_tags'],
                'parameters': fw_spec.get('parameters')
            }

        return FWAction(update_spec=update_spec)
	#bs = mp.get_bandstructure_by_material_id('mp-804')

	i = 0
	while i < len(bs._kpoints):
		for band in bs._bands[Spin.up]:
			band.pop(i)
		bs._kpoints.pop(i)
		i = i + 1

	existkpoints = []
	i = 0
	while i < len(bs._kpoints):
		if any(numpy.array_equal(bs._kpoints[i].frac_coords, kpt) for kpt in existkpoints):
			for band in bs._bands[Spin.up]:
				band.pop(i)
			bs._kpoints.pop(i)
		else:
			existkpoints.append(bs._kpoints[i].frac_coords)
			i = i + 1


	nelec = 38 

	x = BoltztrapRunner(bs, nelec, dos_type="HISTO", energy_grid=0.005, lpfac=10, type="BOLTZ", band_nb=None, tauref=0, tauexp=0, tauen=0, soc=False)
	#goes to nonetype... band structure objects have a ._structure attribute but not .structure
	outfile = x.run(prev_sigma=None, path_dir=os.getcwd(), convergence=True)

	y = BoltztrapAnalyzer.from_files(outfile)
		#adjusted doping levels in boltztrap.outputtrans file in CoSb3 folder
	EffMass = y.get_eig_average_eff_mass_tensor(temperature=300, doping=1e+18)
Esempio n. 13
0
            bs._kpoints.pop(i)
        else:
            existkpoints.append(bs._kpoints[i].frac_coords)
            i = i + 1
    nelec = 44

    x = BoltztrapRunner(bs,
                        nelec,
                        dos_type="HISTO",
                        energy_grid=0.0005,
                        lpfac=5,
                        run_type="BOLTZ",
                        band_nb=None,
                        tauref=0,
                        tauexp=0,
                        tauen=0,
                        soc=False,
                        doping=None,
                        energy_span_around_fermi=0.5,
                        scissor=0.0,
                        kpt_line=None,
                        spin=None,
                        cond_band=False,
                        tmax=1300.0,
                        tgrid=50.0)
    outfile = x.run(path_dir=os.getcwd(),
                    convergence=True,
                    write_input=True,
                    clear_dir=False,
                    max_lpfac=150,
                    min_egrid=0.00005)
Esempio n. 14
0
    def run_task(self, fw_spec):

        # get the band structure and nelect from files
        """
        prev_dir = get_loc(fw_spec['prev_vasp_dir'])
        vasprun_loc = zpath(os.path.join(prev_dir, 'vasprun.xml'))
        kpoints_loc = zpath(os.path.join(prev_dir, 'KPOINTS'))

        vr = Vasprun(vasprun_loc)
        bs = vr.get_band_structure(kpoints_filename=kpoints_loc)
        """

        # get the band structure and nelect from DB
        block_part = get_block_part(fw_spec['prev_vasp_dir'])

        db_dir = os.environ['DB_LOC']
        assert isinstance(db_dir, object)
        db_path = os.path.join(db_dir, 'tasks_db.json')
        with open(db_path) as f:
            creds = json.load(f)
            connection = MongoClient(creds['host'], creds['port'])
            tdb = connection[creds['database']]
            tdb.authenticate(creds['admin_user'], creds['admin_password'])

            m_task = tdb.tasks.find_one({"dir_name": block_part}, {
                "calculations": 1,
                "task_id": 1
            })
            nelect = m_task['calculations'][0]['input']['parameters']['NELECT']
            bs_id = m_task['calculations'][0]['band_structure_fs_id']
            print bs_id, type(bs_id)
            fs = gridfs.GridFS(tdb, 'band_structure_fs')
            bs_dict = json.loads(fs.get(bs_id).read())
            bs_dict['structure'] = m_task['calculations'][0]['output'][
                'crystal']
            bs = BandStructure.from_dict(bs_dict)
            print 'Band Structure found:', bool(bs)
            print nelect

            # run Boltztrap
            runner = BoltztrapRunner(bs, nelect)
            dir = runner.run(path_dir=os.getcwd())

            # put the data in the database
            bta = BoltztrapAnalyzer.from_files(dir)
            data = bta.to_dict
            data.update(get_meta_from_structure(bs._structure))
            data['snlgroup_id'] = fw_spec['snlgroup_id']
            data['run_tags'] = fw_spec['run_tags']
            data['snl'] = fw_spec['mpsnl']
            data['dir_name_full'] = dir
            data['dir_name'] = get_block_part(dir)
            data['task_id'] = m_task['task_id']
            data['hall'] = {}  # remove because it is too large and not useful
            data['hall_doping'] = {
            }  # remove because it is too large and not useful
            tdb.boltztrap.insert(clean_json(data))

        update_spec = {
            'prev_vasp_dir': fw_spec['prev_vasp_dir'],
            'boltztrap_dir': os.getcwd(),
            'prev_task_type': fw_spec['task_type'],
            'mpsnl': fw_spec['mpsnl'],
            'snlgroup_id': fw_spec['snlgroup_id'],
            'run_tags': fw_spec['run_tags'],
            'parameters': fw_spec.get('parameters')
        }

        return FWAction(update_spec=update_spec)
Esempio n. 15
0
    while i < len(bs._kpoints):
        if any(
                numpy.array_equal(bs._kpoints[i].frac_coords, kpt)
                for kpt in existkpoints):
            for band in bs._bands[Spin.up]:
                band.pop(i)
            bs._kpoints.pop(i)
        else:
            existkpoints.append(bs._kpoints[i].frac_coords)
            i = i + 1

    nelec = 38

    x = BoltztrapRunner(bs,
                        nelec,
                        dos_type="HISTO",
                        energy_grid=0.005,
                        lpfac=10,
                        type="BOLTZ",
                        band_nb=None,
                        tauref=0,
                        tauexp=0,
                        tauen=0,
                        soc=False)
    #goes to nonetype... band structure objects have a ._structure attribute but not .structure
    outfile = x.run(prev_sigma=None, path_dir=os.getcwd(), convergence=True)

    y = BoltztrapAnalyzer.from_files(outfile)
    #adjusted doping levels in boltztrap.outputtrans file in CoSb3 folder
    EffMass = y.get_eig_average_eff_mass_tensor(temperature=300, doping=1e+18)
Esempio n. 16
0
 def transport_run(self,doping=[],output_dir='./'):
     BoltztrapRunner(self.bs,self.nelec,doping=doping,symprec=0.1).run(output_dir)
Esempio n. 17
0
 def band_interpolate(self,output_dir='./'):
     BoltztrapRunner(self.bs,self.nelec,run_type='BANDS').run(output_dir)
Esempio n. 18
0
from pymatgen.io.vasp.outputs import Vasprun

from pymatgen.electronic_structure.plotter import BSPlotter, DosPlotter, BSDOSPlotter, BoltztrapPlotter

from pymatgen.electronic_structure.core import Spin, Orbital, OrbitalType

from pymatgen.electronic_structure.dos import Dos

from pymatgen.electronic_structure.boltztrap import BoltztrapRunner, BoltztrapAnalyzer

v_dos = Vasprun("vasprun.xml")
bs = v_dos.get_band_structure()
nelect = v_dos.parameters['NELECT']
vbm = int(nelect / 2 - 1)
BoltztrapRunner(bs=bs,
                nelec=nelect,
                lpfac=100,
                run_type='FERMI',
                band_nb=24,
                cond_band=False,
                spin=1).run(path_dir='./b24/')
an = BoltztrapAnalyzer.from_files("b24/boltztrap/")
BoltztrapPlotter.plot_fermi_surface(an.fermi_surface_data,
                                    bs.structure,
                                    cbm=False,
                                    energy_levels=[-0.01])
Esempio n. 19
0
    def run_task(self, fw_spec):
        # import here to prevent import errors in bigger MPCollab
        # get the band structure and nelect from files
        """
        prev_dir = get_loc(fw_spec['prev_vasp_dir'])
        vasprun_loc = zpath(os.path.join(prev_dir, 'vasprun.xml'))
        kpoints_loc = zpath(os.path.join(prev_dir, 'KPOINTS'))

        vr = Vasprun(vasprun_loc)
        bs = vr.get_band_structure(kpoints_filename=kpoints_loc)
        """
        filename = get_slug(
            'JOB--' + fw_spec['mpsnl'].structure.composition.reduced_formula + '--'
            + fw_spec['task_type'])
        with open(filename, 'w+') as f:
            f.write('')

        # get the band structure and nelect from DB
        block_part = get_block_part(fw_spec['prev_vasp_dir'])

        db_dir = os.environ['DB_LOC']
        assert isinstance(db_dir, object)
        db_path = os.path.join(db_dir, 'tasks_db.json')
        with open(db_path) as f:
            creds = json.load(f)
            connection = MongoClient(creds['host'], creds['port'])
            tdb = connection[creds['database']]
            tdb.authenticate(creds['admin_user'], creds['admin_password'])

            props = {"calculations": 1, "task_id": 1, "state": 1, "pseudo_potential": 1, "run_type": 1, "is_hubbard": 1, "hubbards": 1, "unit_cell_formula": 1}
            m_task = tdb.tasks.find_one({"dir_name": block_part}, props)
            if not m_task:
                time.sleep(60)  # only thing to think of is wait for DB insertion(?)
                m_task = tdb.tasks.find_one({"dir_name": block_part}, props)

            if not m_task:
                raise ValueError("Could not find task with dir_name: {}".format(block_part))

            if m_task['state'] != 'successful':
                raise ValueError("Cannot run Boltztrap; parent job unsuccessful")

            nelect = m_task['calculations'][0]['input']['parameters']['NELECT']
            bs_id = m_task['calculations'][0]['band_structure_fs_id']
            print bs_id, type(bs_id)
            fs = gridfs.GridFS(tdb, 'band_structure_fs')
            bs_dict = json.loads(fs.get(bs_id).read())
            bs_dict['structure'] = m_task['calculations'][0]['output']['crystal']
            bs = BandStructure.from_dict(bs_dict)
            print 'Band Structure found:', bool(bs)
            print nelect

            # run Boltztrap
            runner = BoltztrapRunner(bs, nelect)
            dir = runner.run(path_dir=os.getcwd())

            # put the data in the database
            bta = BoltztrapAnalyzer.from_files(dir)

            # 8/21/15 - Anubhav removed fs_id (also see line further below, ted['boltztrap_full_fs_id'] ...)
            # 8/21/15 - this is to save space in MongoDB, as well as non-use of full Boltztrap output (vs rerun)
            """
            data = bta.as_dict()
            data.update(get_meta_from_structure(bs._structure))
            data['snlgroup_id'] = fw_spec['snlgroup_id']
            data['run_tags'] = fw_spec['run_tags']
            data['snl'] = fw_spec['mpsnl']
            data['dir_name_full'] = dir
            data['dir_name'] = get_block_part(dir)
            data['task_id'] = m_task['task_id']
            del data['hall']  # remove because it is too large and not useful
            fs = gridfs.GridFS(tdb, "boltztrap_full_fs")
            btid = fs.put(json.dumps(jsanitize(data)))
            """

            # now for the "sanitized" data
            ted = bta.as_dict()
            del ted['seebeck']
            del ted['hall']
            del ted['kappa']
            del ted['cond']

            # ted['boltztrap_full_fs_id'] = btid
            ted['snlgroup_id'] = fw_spec['snlgroup_id']
            ted['run_tags'] = fw_spec['run_tags']
            ted['snl'] = fw_spec['mpsnl'].as_dict()
            ted['dir_name_full'] = dir
            ted['dir_name'] = get_block_part(dir)
            ted['task_id'] = m_task['task_id']

            ted['pf_doping'] = bta.get_power_factor(output='tensor', relaxation_time=self.TAU)
            ted['zt_doping'] = bta.get_zt(output='tensor', relaxation_time=self.TAU, kl=self.KAPPAL)

            ted['pf_eigs'] = self.get_eigs(ted, 'pf_doping')
            ted['pf_best'] = self.get_extreme(ted, 'pf_eigs')
            ted['pf_best_dope18'] = self.get_extreme(ted, 'pf_eigs', max_didx=3)
            ted['pf_best_dope19'] = self.get_extreme(ted, 'pf_eigs', max_didx=4)
            ted['zt_eigs'] = self.get_eigs(ted, 'zt_doping')
            ted['zt_best'] = self.get_extreme(ted, 'zt_eigs')
            ted['zt_best_dope18'] = self.get_extreme(ted, 'zt_eigs', max_didx=3)
            ted['zt_best_dope19'] = self.get_extreme(ted, 'zt_eigs', max_didx=4)
            ted['seebeck_eigs'] = self.get_eigs(ted, 'seebeck_doping')
            ted['seebeck_best'] = self.get_extreme(ted, 'seebeck_eigs')
            ted['seebeck_best_dope18'] = self.get_extreme(ted, 'seebeck_eigs', max_didx=3)
            ted['seebeck_best_dope19'] = self.get_extreme(ted, 'seebeck_eigs', max_didx=4)
            ted['cond_eigs'] = self.get_eigs(ted, 'cond_doping')
            ted['cond_best'] = self.get_extreme(ted, 'cond_eigs')
            ted['cond_best_dope18'] = self.get_extreme(ted, 'cond_eigs', max_didx=3)
            ted['cond_best_dope19'] = self.get_extreme(ted, 'cond_eigs', max_didx=4)
            ted['kappa_eigs'] = self.get_eigs(ted, 'kappa_doping')
            ted['kappa_best'] = self.get_extreme(ted, 'kappa_eigs', maximize=False)
            ted['kappa_best_dope18'] = self.get_extreme(ted, 'kappa_eigs', maximize=False, max_didx=3)
            ted['kappa_best_dope19'] = self.get_extreme(ted, 'kappa_eigs', maximize=False, max_didx=4)

            try:
	        from mpcollab.thermoelectrics.boltztrap_TE import BoltzSPB
                bzspb = BoltzSPB(ted)
                maxpf_p = bzspb.get_maximum_power_factor('p', temperature=0, tau=1E-14, ZT=False, kappal=0.5,\
                    otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \
                                                    'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu'))

                maxpf_n = bzspb.get_maximum_power_factor('n', temperature=0, tau=1E-14, ZT=False, kappal=0.5,\
                    otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \
                                                    'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu'))

                maxzt_p = bzspb.get_maximum_power_factor('p', temperature=0, tau=1E-14, ZT=True, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \
                                                    'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu'))

                maxzt_n = bzspb.get_maximum_power_factor('n', temperature=0, tau=1E-14, ZT=True, kappal=0.5, otherprops=('get_seebeck_mu_eig', 'get_conductivity_mu_eig', \
                                                    'get_thermal_conductivity_mu_eig', 'get_average_eff_mass_tensor_mu'))

                ted['zt_best_finemesh'] = {'p': maxzt_p, 'n': maxzt_n}
                ted['pf_best_finemesh'] = {'p': maxpf_p, 'n': maxpf_n}
            except:
                import traceback
                traceback.print_exc()
                print 'COULD NOT GET FINE MESH DATA'

            # add is_compatible
            mpc = MaterialsProjectCompatibility("Advanced")
            try:
                func = m_task["pseudo_potential"]["functional"]
                labels = m_task["pseudo_potential"]["labels"]
                symbols = ["{} {}".format(func, label) for label in labels]
                parameters = {"run_type": m_task["run_type"],
                          "is_hubbard": m_task["is_hubbard"],
                          "hubbards": m_task["hubbards"],
                          "potcar_symbols": symbols}
                entry = ComputedEntry(Composition(m_task["unit_cell_formula"]),
                                      0.0, 0.0, parameters=parameters,
                                      entry_id=m_task["task_id"])

                ted["is_compatible"] = bool(mpc.process_entry(entry))
            except:
                traceback.print_exc()
                print 'ERROR in getting compatibility, task_id: {}'.format(m_task["task_id"])
                ted["is_compatible"] = None

            tdb.boltztrap.insert(jsanitize(ted))

            update_spec = {'prev_vasp_dir': fw_spec['prev_vasp_dir'],
                       'boltztrap_dir': os.getcwd(),
                       'prev_task_type': fw_spec['task_type'],
                       'mpsnl': fw_spec['mpsnl'].as_dict(),
                       'snlgroup_id': fw_spec['snlgroup_id'],
                       'run_tags': fw_spec['run_tags'], 'parameters': fw_spec.get('parameters')}

        return FWAction(update_spec=update_spec)
Esempio n. 20
0
class BoltztrapAnalyzerTest(unittest.TestCase):

    def setUp(self):
        self.bz = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/transp/"))
        self.bz_bands = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/bands/"))
        self.bz_up = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/dos_up/"), dos_spin=1)
        self.bz_dw = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/dos_dw/"), dos_spin=-1)
        self.bz_fermi = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/fermi/"))

        with open(os.path.join(test_dir, "Cu2O_361_bandstructure.json"),
                  "rt") as f:
            d = json.load(f)
            self.bs = BandStructure.from_dict(d)
            self.btr = BoltztrapRunner(self.bs, 1)
        warnings.simplefilter("ignore")

    def tearDown(self):
        warnings.resetwarnings()

    def test_properties(self):
        self.assertAlmostEqual(self.bz.gap, 1.6644932121620404, 4)
        array = self.bz._cond[300][102]
        self.assertAlmostEqual(array[0][0] / 1e19, 7.5756518, 4)
        self.assertAlmostEqual(array[0][2], -11.14679)
        self.assertAlmostEqual(array[1][0], -88.203286)
        self.assertAlmostEqual(array[2][2], 1.7133249e+19)
        array = self.bz._seebeck[300][22]
        self.assertAlmostEqual(array[0][1], 6.4546074e-22)
        self.assertAlmostEqual(array[1][1], -0.00032073711)
        self.assertAlmostEqual(array[1][2], -2.9868424e-24)
        self.assertAlmostEqual(array[2][2], -0.0003126543)
        array = self.bz._kappa[500][300]
        self.assertAlmostEqual(array[0][1], 0.00014524309)
        self.assertAlmostEqual(array[1][1], 328834400000000.0)
        self.assertAlmostEqual(array[1][2], 3.7758069e-05)
        self.assertAlmostEqual(array[2][2], 193943750000000.0)
        self.assertAlmostEqual(self.bz._hall[400][800][1][0][0], 9.5623749e-28)
        self.assertAlmostEqual(self.bz._hall[400][68][1][2][2], 6.5106975e-10)
        self.assertAlmostEqual(self.bz.doping['p'][3], 1e18)
        self.assertAlmostEqual(self.bz.mu_doping['p'][300][2], 0.1553770018406)
        self.assertAlmostEqual(self.bz.mu_doping['n'][300][-1],
                               1.6486017632924719, 4)
        self.assertAlmostEqual(self.bz._cond_doping['n'][800][3][1][1] / 1e16,
                               1.5564085, 4)
        self.assertAlmostEqual(self.bz._seebeck_doping['p'][600][2][0][
                                   1] / 1e-23, 3.2860613, 4)
        self.assertAlmostEqual(self.bz._carrier_conc[500][67], 38.22832002)
        self.assertAlmostEqual(self.bz.vol, 612.97557323964838, 4)
        self.assertAlmostEqual(self.bz.intrans["scissor"], 0.0, 1)
        self.assertAlmostEqual(self.bz._hall_doping['n'][700][-1][2][2][2],
                               5.0136483e-26)
        self.assertAlmostEqual(self.bz.dos.efermi, -0.0300005507057)
        self.assertAlmostEqual(self.bz.dos.energies[0], -2.4497049391830448, 4)
        self.assertAlmostEqual(self.bz.dos.energies[345],
                               -0.72708823447130944, 4)
        self.assertAlmostEqual(self.bz.dos.energies[-1], 3.7569398770153524, 4)
        self.assertAlmostEqual(self.bz.dos.densities[Spin.up][400], 118.70171)
        self.assertAlmostEqual(self.bz.dos.densities[Spin.up][200], 179.58562)
        self.assertAlmostEqual(self.bz.dos.densities[Spin.up][300], 289.43945)

        self.assertAlmostEqual(self.bz_bands._bz_bands.shape, (1316, 20))
        self.assertAlmostEqual(self.bz_bands._bz_kpoints.shape, (1316, 3))
        self.assertAlmostEqual(self.bz_up._dos_partial['0']['pz'][2562],
                               0.023862958)
        self.assertAlmostEqual(self.bz_dw._dos_partial['1']['px'][3120],
                               5.0192891)
        self.assertAlmostEqual(self.bz_fermi.fermi_surface_data.shape,
                               (121, 121, 65))
        self.assertAlmostEqual(self.bz_fermi.fermi_surface_data[21][79][19],
                               -1.8831911809439161, 5)

    @unittest.skipIf(not fdint, "No FDINT")
    def test_get_seebeck_eff_mass(self):
        ref = [1.956090529381193, 2.0339311618566343, 1.1529383757896965]
        ref2 = [4258.4072823354145, 4597.0351887125289, 4238.1262696392705]
        sbk_mass_tens_mu = \
        self.bz.get_seebeck_eff_mass(output='tensor', doping_levels=False,
                                     temp=300)[3]
        sbk_mass_tens_dop = \
        self.bz.get_seebeck_eff_mass(output='tensor', doping_levels=True,
                                     temp=300)['n'][2]
        sbk_mass_avg_mu = \
        self.bz.get_seebeck_eff_mass(output='average', doping_levels=False,
                                     temp=300)[3]
        sbk_mass_avg_dop = \
        self.bz.get_seebeck_eff_mass(output='average', doping_levels=True,
                                     temp=300)['n'][2]

        for i in range(0, 3):
            self.assertAlmostEqual(sbk_mass_tens_mu[i], ref2[i], 1)
            self.assertAlmostEqual(sbk_mass_tens_dop[i], ref[i], 4)

        self.assertAlmostEqual(sbk_mass_avg_mu, 4361.4744008038842, 1)
        self.assertAlmostEqual(sbk_mass_avg_dop, 1.661553842105382, 4)

    @unittest.skipIf(not fdint, "No FDINT")
    def test_get_complexity_factor(self):
        ref = [2.7658776815227828, 2.9826088215568403, 0.28881335881640308]
        ref2 = [0.0112022048620205, 0.0036001049607186602,
                0.0083028947173193028]
        sbk_mass_tens_mu = \
        self.bz.get_complexity_factor(output='tensor', doping_levels=False,
                                      temp=300)[3]
        sbk_mass_tens_dop = \
        self.bz.get_complexity_factor(output='tensor', doping_levels=True,
                                      temp=300)['n'][2]
        sbk_mass_avg_mu = \
        self.bz.get_complexity_factor(output='average', doping_levels=False,
                                      temp=300)[3]
        sbk_mass_avg_dop = \
        self.bz.get_complexity_factor(output='average', doping_levels=True,
                                      temp=300)['n'][2]

        for i in range(0, 3):
            self.assertAlmostEqual(sbk_mass_tens_mu[i], ref2[i], 4)
            self.assertAlmostEqual(sbk_mass_tens_dop[i], ref[i], 4)

        self.assertAlmostEqual(sbk_mass_avg_mu, 0.00628677029221, 4)
        self.assertAlmostEqual(sbk_mass_avg_dop, 1.12322832119, 4)

    def test_get_seebeck(self):
        ref = [-768.99078999999995, -724.43919999999991, -686.84682999999973]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_seebeck()['n'][800][3][i],
                                   ref[i])
        self.assertAlmostEqual(
            self.bz.get_seebeck(output='average')['p'][800][3], 697.608936667)
        self.assertAlmostEqual(
            self.bz.get_seebeck(output='average', doping_levels=False)[500][
                520], 1266.7056)
        self.assertAlmostEqual(
            self.bz.get_seebeck(output='average', doping_levels=False)[300][65],
            -36.2459389333)  # TODO: this was originally "eigs"

    def test_get_conductivity(self):
        ref = [5.9043185000000022, 17.855599000000002, 26.462935000000002]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_conductivity()['p'][600][2][i],
                                   ref[i])
        self.assertAlmostEqual(
            self.bz.get_conductivity(output='average')['n'][700][1],
            1.58736609667)
        self.assertAlmostEqual(
            self.bz.get_conductivity(output='average', doping_levels=False)[
                300][457], 2.87163566667)
        self.assertAlmostEqual(
            self.bz.get_conductivity(output='average', doping_levels=False,
                                     # TODO: this was originally "eigs"
                                     relaxation_time=1e-15)[200][63],
            16573.0536667)

    def test_get_power_factor(self):
        ref = [6.2736602345523362, 17.900184232304138, 26.158282220458144]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_power_factor()['p'][200][2][i],
                                   ref[i])
        self.assertAlmostEqual(
            self.bz.get_power_factor(output='average')['n'][600][4],
            411.230962976)
        self.assertAlmostEqual(
            self.bz.get_power_factor(output='average', doping_levels=False,
                                     relaxation_time=1e-15)[500][459],
            6.59277148467)
        self.assertAlmostEqual(
            self.bz.get_power_factor(output='average', doping_levels=False)[
                800][61], 2022.67064134)  # TODO: this was originally "eigs"

    def test_get_thermal_conductivity(self):
        ref = [2.7719565628862623e-05, 0.00010048046886793946,
               0.00015874549392499391]
        for i in range(0, 3):
            self.assertAlmostEqual(
                self.bz.get_thermal_conductivity()['p'][300][2][i], ref[i])
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(output='average',
                                             relaxation_time=1e-15)['n'][500][
                0],
            1.74466575612e-07)
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(output='average',
                                             doping_levels=False)[800][874],
            8.08066254813)
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(output='average',
                                             doping_levels=False)[200][32],
            # TODO: this was originally "eigs"
            0.0738961845832)
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(k_el=False, output='average',
                                             doping_levels=False)[200][32],
            0.19429052)

    def test_get_zt(self):
        ref = [0.097408810215, 0.29335112354, 0.614673998089]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_zt()['n'][800][4][i], ref[i])
        self.assertAlmostEqual(
            self.bz.get_zt(output='average', kl=0.5)['p'][700][2],
            0.0170001879916)
        self.assertAlmostEqual(
            self.bz.get_zt(output='average', doping_levels=False,
                           relaxation_time=1e-15)[300][240],
            0.0041923533238348342)

        eigs = self.bz.get_zt(output='eigs', doping_levels=False)[700][65]
        ref_eigs = [0.082420053399668847, 0.29408035502671648,
                    0.40822061215079392]
        for idx, val in enumerate(ref_eigs):
            self.assertAlmostEqual(eigs[idx], val, 5)

    def test_get_average_eff_mass(self):
        ref = [0.76045816788363574, 0.96181142990667101, 2.9428428773308628]
        for i in range(0, 3):
            self.assertAlmostEqual(
                self.bz.get_average_eff_mass()['p'][300][2][i], ref[i])
        ref = [1.1295783824744523, 1.3898454041924351, 5.2459984671977935]
        ref2 = [6.6648842712692078, 31.492540105738343, 37.986369302138954]
        for i in range(0, 3):
            self.assertAlmostEqual(
                self.bz.get_average_eff_mass()['n'][600][1][i], ref[i])
            self.assertAlmostEqual(
                self.bz.get_average_eff_mass(doping_levels=False)[300][200][i],
                ref2[i])
        ref = [[9.61811430e-01, -8.25159596e-19, -4.70319444e-19],
               [-8.25159596e-19, 2.94284288e+00, 3.00368916e-18],
               [-4.70319444e-19, 3.00368916e-18, 7.60458168e-01]]
        ref2 = [[2.79760445e+01, -2.39347589e-17, -1.36897140e-17],
                [-2.39347589e-17, 8.55969097e+01, 8.74169648e-17],
                [-1.36897140e-17, 8.74169648e-17, 2.21151980e+01]]

        for i in range(0, 3):
            for j in range(0, 3):
                self.assertAlmostEqual(
                    self.bz.get_average_eff_mass(output='tensor')['p'][300][2][
                        i][j], ref[i][j])
                self.assertAlmostEqual(
                    self.bz.get_average_eff_mass(output='tensor',
                                                 doping_levels=False)[300][500][
                        i][j], ref2[i][j])
        self.assertAlmostEqual(
            self.bz.get_average_eff_mass(output='average')['n'][300][2],
            1.53769093989)

    def test_get_carrier_concentration(self):
        self.assertAlmostEqual(self.bz.get_carrier_concentration()[300][39] /
                               1e22, 6.4805156617179151, 4)
        self.assertAlmostEqual(self.bz.get_carrier_concentration()[300][
                                   693] / 1e15, -6.590800965604750, 4)

    def test_get_hall_carrier_concentration(self):
        self.assertAlmostEqual(self.bz.get_hall_carrier_concentration()[600][
                                   120] / 1e21, 6.773394626767555, 4)
        self.assertAlmostEqual(self.bz.get_hall_carrier_concentration()[500][
                                   892] / 1e21, -9.136803845741777, 4)

    def test_get_symm_bands(self):
        structure = loadfn(
            os.path.join(test_dir, 'boltztrap/structure_mp-12103.json'))
        sbs = loadfn(os.path.join(test_dir, 'boltztrap/dft_bs_sym_line.json'))
        kpoints = [kp.frac_coords for kp in sbs.kpoints]
        labels_dict = {k: sbs.labels_dict[k].frac_coords for k in
                       sbs.labels_dict}
        for kpt_line, labels_dict in zip([None, sbs.kpoints, kpoints],
                                         [None, sbs.labels_dict, labels_dict]):
            sbs_bzt = self.bz_bands.get_symm_bands(structure, -5.25204548,
                                                   kpt_line=kpt_line,
                                                   labels_dict=labels_dict)
            self.assertAlmostEqual(len(sbs_bzt.bands[Spin.up]), 20)
            self.assertAlmostEqual(len(sbs_bzt.bands[Spin.up][1]), 143)

    # def test_check_acc_bzt_bands(self):
    #     structure = loadfn(os.path.join(test_dir,'boltztrap/structure_mp-12103.json'))
    #     sbs = loadfn(os.path.join(test_dir,'boltztrap/dft_bs_sym_line.json'))
    #     sbs_bzt = self.bz_bands.get_symm_bands(structure,-5.25204548)
    #     corr,werr_vbm,werr_cbm,warn = BoltztrapAnalyzer.check_acc_bzt_bands(sbs_bzt,sbs)
    #     self.assertAlmostEqual(corr[2],9.16851750e-05)
    #     self.assertAlmostEqual(werr_vbm['K-H'],0.18260273521047862)
    #     self.assertAlmostEqual(werr_cbm['M-K'],0.071552669981356981)
    #     self.assertFalse(warn)

    def test_get_complete_dos(self):
        structure = loadfn(
            os.path.join(test_dir, 'boltztrap/structure_mp-12103.json'))
        cdos = self.bz_up.get_complete_dos(structure, self.bz_dw)
        spins = list(cdos.densities.keys())
        self.assertIn(Spin.down, spins)
        self.assertIn(Spin.up, spins)
        self.assertAlmostEqual(
            cdos.get_spd_dos()[OrbitalType.p].densities[Spin.up][3134],
            43.839230100999991)
        self.assertAlmostEqual(
            cdos.get_spd_dos()[OrbitalType.s].densities[Spin.down][716],
            6.5383268000000001)

    def test_extreme(self):
        x = self.bz.get_extreme("seebeck")
        self.assertEqual(x["best"]["carrier_type"], "n")
        self.assertAlmostEqual(x["p"]["value"], 1255.365, 2)
        self.assertEqual(x["n"]["isotropic"], True)
        self.assertEqual(x["n"]["temperature"], 600)

        x = self.bz.get_extreme("kappa", maximize=False, min_temp=400,
                                min_doping=1E20)
        self.assertAlmostEqual(x["best"]["value"], 0.105, 2)
        self.assertAlmostEqual(x["n"]["value"], 0.139, 2)
        self.assertEqual(x["p"]["temperature"], 400)
        self.assertEqual(x["n"]["isotropic"], False)

    def test_to_from_dict(self):
        btr_dict = self.btr.as_dict()
        s = json.dumps(btr_dict)
        self.assertIsNotNone(s)
        self.assertIsNotNone(btr_dict['bs'])
Esempio n. 21
0
def boltztrap(tmax=1000,
              tstep=10,
              doping=np.logspace(18, 21, 100),
              vasprun='vasprun.xml',
              soc=False,
              zero_weighted=False,
              kpoints=None,
              lpfac=10,
              relaxation_time=1e-14,
              run=True,
              analyse=True,
              output='boltztrap.hdf5'):
    """Runs BoltzTraP

    Runs quicker than the pymatgen from_files version.
    Also writes to a hdf5 file.
    Minimum temperature is always 200 K, because BoltzTraP.
    Note: BoltzTraP can be a fickle friend, so if you're getting errors,
    it may be worth reinstalling or trying on a different machine.
    Testing with a small number of temperature/ doping combinations is also
    recommended

    Arguments:
        tmax : float, optional
            maximum temperature in K. Default: 1000.
        tstep : float, optional
            temperature step in K. Default: 10.
        doping : array-like, optional
            doping concentrations in cm-1. Default: np.logspace(18, 21, 101).

        vasprun : str, optional
            path to vasprun. Default: vasprun.xml.
        soc : bool, optional
            spin orbit coupling used. Default: False.
        zero_weighted : bool, optional
            zero weighted kpoints used. Default: False.
        kpoints : str, optional
            path to KPOINTS file if zero_weighted. Default: KPOINTS.
        lpfac : int, optional
            interpolate the DoS k-points by lpfac times. Default: 10.
        relaxation_time : float, optional
            charge carrier relaxation time. Default: 1e-14.

        run : bool, optional
            run BoltzTraP. Default: True.
        analyse : bool, optional
            analyse BoltzTraP. Default: True.
        output : str, optional
            output hdf5 filename. Default: boltztrap.hdf5.
    """

    import h5py
    import os
    from multiprocessing import Pool
    from pymatgen.electronic_structure.boltztrap import BoltztrapRunner, BoltztrapAnalyzer
    from pymatgen.io.vasp.outputs import Vasprun
    from scipy import constants

    for v, w in zip(['tmax', 'tstep', 'lpfac', 'relaxation_time'],
                    [tmax, tstep, lpfac, relaxation_time]):
        assert isinstance(w, (float, int)), '{} must be a number'.forpmat(v)
    for v, w in zip(['soc,', 'zero_weighted', 'run', 'analyse'],
                    [soc, zero_weighted, run, analyse]):
        assert isinstance(w, bool), '{} must be True or False'.forpmat(v)

    temperature = np.arange(200, tmax, tstep)

    if run:  # run boltztrap from vasprun.xml -> boltztrap directory
        doping = np.array(doping)
        vr = Vasprun(vasprun)
        bs = vr.get_band_structure(line_mode=zero_weighted,
                                   kpoints_filename=kpoints)
        nelect = vr.parameters['NELECT']

        btr = BoltztrapRunner(bs,
                              nelect,
                              doping=list(doping),
                              tmax=tmax,
                              tgrid=tstep,
                              lpfac=lpfac)
        print('Running Boltztrap...', end='')
        btr_dir = btr.run(path_dir='.')
        print('Done.')

    else:
        btr_dir = 'boltztrap'

    if analyse:  # run boltztrap from boltztrap directory -> hdf5 file
        print('Analysing Boltztrap...', end='')
        bta = BoltztrapAnalyzer.from_files(btr_dir)
        print('Done.')

        data = {
            'average_eff_mass': {},
            'conductivity': {},
            'doping': doping,
            'power_factor': {},
            'seebeck': {},
            'temperature': temperature,
            'thermal_conductivity': {}
        }

        # load data

        print('Calculating transport...', end='')
        c = bta._cond_doping
        dp = bta.doping
        e = constants.e
        f = bta.mu_doping
        k = bta._kappa_doping
        me = constants.m_e
        s = bta._seebeck_doping

        # calculate transport properties

        for d in ['n', 'p']:
            c[d] = np.array([c[d][t] for t in temperature])
            dp[d] = np.array(dp[d])
            k[d] = np.array([k[d][t] for t in temperature])
            f[d] = np.array([f[d][t] for t in temperature])
            s[d] = np.array([s[d][t] for t in temperature])
            data['average_eff_mass'][d] = np.linalg.inv(c[d]) \
                                        * dp[d][None, :, None, None] \
                                        * 1e6 * e ** 2 / me
            data['conductivity'][d] = np.multiply(c[d], relaxation_time)
            data['seebeck'][d] = np.multiply(s[d], 1e6)
            data['power_factor'][d] = tp.calculate.power_factor(c[d], s[d])
            data['thermal_conductivity'][d] = (k[d] - s[d] ** 2 * c[d] \
                                            * temperature[:,None,None,None]) \
                                            * relaxation_time
        data['fermi_level'] = f
        print('Done.')

        # write data

        datafile = h5py.File(output, 'w')
        for key in data.keys():
            if isinstance(data[key], dict):
                group = datafile.create_group(key)
                for k in data[key].keys():
                    group[k] = data[key][k]
            else:
                datafile.create_dataset(key,
                                        np.shape(data[key]),
                                        data=data[key])
        datafile.close()

    return
Esempio n. 22
0
    def run_task(self, fw_spec):

        # get the band structure and nelect from files
        """
        prev_dir = get_loc(fw_spec['prev_vasp_dir'])
        vasprun_loc = zpath(os.path.join(prev_dir, 'vasprun.xml'))
        kpoints_loc = zpath(os.path.join(prev_dir, 'KPOINTS'))

        vr = Vasprun(vasprun_loc)
        bs = vr.get_band_structure(kpoints_filename=kpoints_loc)
        """

        # get the band structure and nelect from DB
        block_part = get_block_part(fw_spec['prev_vasp_dir'])

        db_dir = os.environ['DB_LOC']
        assert isinstance(db_dir, object)
        db_path = os.path.join(db_dir, 'tasks_db.json')
        with open(db_path) as f:
            creds = json.load(f)
            connection = MongoClient(creds['host'], creds['port'])
            tdb = connection[creds['database']]
            tdb.authenticate(creds['admin_user'], creds['admin_password'])

            m_task = tdb.tasks.find_one({"dir_name": block_part}, {"calculations": 1, "task_id": 1})
            nelect = m_task['calculations'][0]['input']['parameters']['NELECT']
            bs_id = m_task['calculations'][0]['band_structure_fs_id']
            print bs_id, type(bs_id)
            fs = gridfs.GridFS(tdb, 'band_structure_fs')
            bs_dict = json.loads(fs.get(bs_id).read())
            bs_dict['structure'] = m_task['calculations'][0]['output']['crystal']
            bs = BandStructure.from_dict(bs_dict)
            print 'Band Structure found:', bool(bs)
            print nelect

            # run Boltztrap
            runner = BoltztrapRunner(bs, nelect)
            dir = runner.run(path_dir=os.getcwd())

            # put the data in the database
            bta = BoltztrapAnalyzer.from_files(dir)
            data = bta.to_dict
            data.update(get_meta_from_structure(bs._structure))
            data['snlgroup_id'] = fw_spec['snlgroup_id']
            data['run_tags'] = fw_spec['run_tags']
            data['snl'] = fw_spec['mpsnl']
            data['dir_name_full'] = dir
            data['dir_name'] = get_block_part(dir)
            data['task_id'] = m_task['task_id']
            data['hall'] = {}  # remove because it is too large and not useful
            data['hall_doping'] = {}  # remove because it is too large and not useful
            tdb.boltztrap.insert(clean_json(data))

        update_spec = {'prev_vasp_dir': fw_spec['prev_vasp_dir'],
                       'boltztrap_dir': os.getcwd(),
                       'prev_task_type': fw_spec['task_type'],
                       'mpsnl': fw_spec['mpsnl'],
                       'snlgroup_id': fw_spec['snlgroup_id'],
                       'run_tags': fw_spec['run_tags'], 'parameters': fw_spec.get('parameters')}

        return FWAction(update_spec=update_spec)
Esempio n. 23
0
class BoltztrapAnalyzerTest(unittest.TestCase):
    def setUp(self):
        self.bz = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/transp/"))
        self.bz_bands = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/bands/"))
        self.bz_up = BoltztrapAnalyzer.from_files(os.path.join(
            test_dir, "boltztrap/dos_up/"),
                                                  dos_spin=1)
        self.bz_dw = BoltztrapAnalyzer.from_files(os.path.join(
            test_dir, "boltztrap/dos_dw/"),
                                                  dos_spin=-1)
        self.bz_fermi = BoltztrapAnalyzer.from_files(
            os.path.join(test_dir, "boltztrap/fermi/"))

        with open(os.path.join(test_dir, "Cu2O_361_bandstructure.json"),
                  "rt") as f:
            d = json.load(f)
            self.bs = BandStructure.from_dict(d)
            self.btr = BoltztrapRunner(self.bs, 1)
        warnings.simplefilter("ignore")

    def tearDown(self):
        warnings.resetwarnings()

    def test_properties(self):
        self.assertAlmostEqual(self.bz.gap, 1.6644932121620404, 4)
        array = self.bz._cond[300][102]
        self.assertAlmostEqual(array[0][0] / 1e19, 7.5756518, 4)
        self.assertAlmostEqual(array[0][2], -11.14679)
        self.assertAlmostEqual(array[1][0], -88.203286)
        self.assertAlmostEqual(array[2][2], 1.7133249e+19)
        array = self.bz._seebeck[300][22]
        self.assertAlmostEqual(array[0][1], 6.4546074e-22)
        self.assertAlmostEqual(array[1][1], -0.00032073711)
        self.assertAlmostEqual(array[1][2], -2.9868424e-24)
        self.assertAlmostEqual(array[2][2], -0.0003126543)
        array = self.bz._kappa[500][300]
        self.assertAlmostEqual(array[0][1], 0.00014524309)
        self.assertAlmostEqual(array[1][1], 328834400000000.0)
        self.assertAlmostEqual(array[1][2], 3.7758069e-05)
        self.assertAlmostEqual(array[2][2], 193943750000000.0)
        self.assertAlmostEqual(self.bz._hall[400][800][1][0][0], 9.5623749e-28)
        self.assertAlmostEqual(self.bz._hall[400][68][1][2][2], 6.5106975e-10)
        self.assertAlmostEqual(self.bz.doping['p'][3], 1e18)
        self.assertAlmostEqual(self.bz.mu_doping['p'][300][2], 0.1553770018406)
        self.assertAlmostEqual(self.bz.mu_doping['n'][300][-1],
                               1.6486017632924719, 4)
        self.assertAlmostEqual(self.bz._cond_doping['n'][800][3][1][1] / 1e16,
                               1.5564085, 4)
        self.assertAlmostEqual(
            self.bz._seebeck_doping['p'][600][2][0][1] / 1e-23, 3.2860613, 4)
        self.assertAlmostEqual(self.bz._carrier_conc[500][67], 38.22832002)
        self.assertAlmostEqual(self.bz.vol, 612.97557323964838, 4)
        self.assertAlmostEqual(self.bz.intrans["scissor"], 0.0, 1)
        self.assertAlmostEqual(self.bz._hall_doping['n'][700][-1][2][2][2],
                               5.0136483e-26)
        self.assertAlmostEqual(self.bz.dos.efermi, -0.0300005507057)
        self.assertAlmostEqual(self.bz.dos.energies[0], -2.4497049391830448, 4)
        self.assertAlmostEqual(self.bz.dos.energies[345], -0.72708823447130944,
                               4)
        self.assertAlmostEqual(self.bz.dos.energies[-1], 3.7569398770153524, 4)
        self.assertAlmostEqual(self.bz.dos.densities[Spin.up][400], 118.70171)
        self.assertAlmostEqual(self.bz.dos.densities[Spin.up][200], 179.58562)
        self.assertAlmostEqual(self.bz.dos.densities[Spin.up][300], 289.43945)

        self.assertAlmostEqual(self.bz_bands._bz_bands.shape, (1316, 20))
        self.assertAlmostEqual(self.bz_bands._bz_kpoints.shape, (1316, 3))
        self.assertAlmostEqual(self.bz_up._dos_partial['0']['pz'][2562],
                               0.023862958)
        self.assertAlmostEqual(self.bz_dw._dos_partial['1']['px'][3120],
                               5.0192891)
        self.assertAlmostEqual(self.bz_fermi.fermi_surface_data.shape,
                               (121, 121, 65))
        self.assertAlmostEqual(self.bz_fermi.fermi_surface_data[21][79][19],
                               -1.8831911809439161, 5)

    @unittest.skipIf(not fdint, "No FDINT")
    def test_get_seebeck_eff_mass(self):
        ref = [1.956090529381193, 2.0339311618566343, 1.1529383757896965]
        ref2 = [4258.4072823354145, 4597.0351887125289, 4238.1262696392705]
        sbk_mass_tens_mu = \
        self.bz.get_seebeck_eff_mass(output='tensor', doping_levels=False,
                                     temp=300)[3]
        sbk_mass_tens_dop = \
        self.bz.get_seebeck_eff_mass(output='tensor', doping_levels=True,
                                     temp=300)['n'][2]
        sbk_mass_avg_mu = \
        self.bz.get_seebeck_eff_mass(output='average', doping_levels=False,
                                     temp=300)[3]
        sbk_mass_avg_dop = \
        self.bz.get_seebeck_eff_mass(output='average', doping_levels=True,
                                     temp=300)['n'][2]

        for i in range(0, 3):
            self.assertAlmostEqual(sbk_mass_tens_mu[i], ref2[i], 1)
            self.assertAlmostEqual(sbk_mass_tens_dop[i], ref[i], 4)

        self.assertAlmostEqual(sbk_mass_avg_mu, 4361.4744008038842, 1)
        self.assertAlmostEqual(sbk_mass_avg_dop, 1.661553842105382, 4)

    @unittest.skipIf(not fdint, "No FDINT")
    def test_get_complexity_factor(self):
        ref = [2.7658776815227828, 2.9826088215568403, 0.28881335881640308]
        ref2 = [
            0.0112022048620205, 0.0036001049607186602, 0.0083028947173193028
        ]
        sbk_mass_tens_mu = \
        self.bz.get_complexity_factor(output='tensor', doping_levels=False,
                                      temp=300)[3]
        sbk_mass_tens_dop = \
        self.bz.get_complexity_factor(output='tensor', doping_levels=True,
                                      temp=300)['n'][2]
        sbk_mass_avg_mu = \
        self.bz.get_complexity_factor(output='average', doping_levels=False,
                                      temp=300)[3]
        sbk_mass_avg_dop = \
        self.bz.get_complexity_factor(output='average', doping_levels=True,
                                      temp=300)['n'][2]

        for i in range(0, 3):
            self.assertAlmostEqual(sbk_mass_tens_mu[i], ref2[i], 4)
            self.assertAlmostEqual(sbk_mass_tens_dop[i], ref[i], 4)

        self.assertAlmostEqual(sbk_mass_avg_mu, 0.00628677029221, 4)
        self.assertAlmostEqual(sbk_mass_avg_dop, 1.12322832119, 4)

    def test_get_seebeck(self):
        ref = [-768.99078999999995, -724.43919999999991, -686.84682999999973]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_seebeck()['n'][800][3][i],
                                   ref[i])
        self.assertAlmostEqual(
            self.bz.get_seebeck(output='average')['p'][800][3], 697.608936667)
        self.assertAlmostEqual(
            self.bz.get_seebeck(output='average',
                                doping_levels=False)[500][520], 1266.7056)
        self.assertAlmostEqual(
            self.bz.get_seebeck(output='average',
                                doping_levels=False)[300][65],
            -36.2459389333)  # TODO: this was originally "eigs"

    def test_get_conductivity(self):
        ref = [5.9043185000000022, 17.855599000000002, 26.462935000000002]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_conductivity()['p'][600][2][i],
                                   ref[i])
        self.assertAlmostEqual(
            self.bz.get_conductivity(output='average')['n'][700][1],
            1.58736609667)
        self.assertAlmostEqual(
            self.bz.get_conductivity(output='average',
                                     doping_levels=False)[300][457],
            2.87163566667)
        self.assertAlmostEqual(
            self.bz.get_conductivity(
                output='average',
                doping_levels=False,
                # TODO: this was originally "eigs"
                relaxation_time=1e-15)[200][63],
            16573.0536667)

    def test_get_power_factor(self):
        ref = [6.2736602345523362, 17.900184232304138, 26.158282220458144]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_power_factor()['p'][200][2][i],
                                   ref[i])
        self.assertAlmostEqual(
            self.bz.get_power_factor(output='average')['n'][600][4],
            411.230962976)
        self.assertAlmostEqual(
            self.bz.get_power_factor(output='average',
                                     doping_levels=False,
                                     relaxation_time=1e-15)[500][459],
            6.59277148467)
        self.assertAlmostEqual(
            self.bz.get_power_factor(output='average',
                                     doping_levels=False)[800][61],
            2022.67064134)  # TODO: this was originally "eigs"

    def test_get_thermal_conductivity(self):
        ref = [
            2.7719565628862623e-05, 0.00010048046886793946,
            0.00015874549392499391
        ]
        for i in range(0, 3):
            self.assertAlmostEqual(
                self.bz.get_thermal_conductivity()['p'][300][2][i], ref[i])
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(
                output='average', relaxation_time=1e-15)['n'][500][0],
            1.74466575612e-07)
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(output='average',
                                             doping_levels=False)[800][874],
            8.08066254813)
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(output='average',
                                             doping_levels=False)[200][32],
            # TODO: this was originally "eigs"
            0.0738961845832)
        self.assertAlmostEqual(
            self.bz.get_thermal_conductivity(k_el=False,
                                             output='average',
                                             doping_levels=False)[200][32],
            0.19429052)

    def test_get_zt(self):
        ref = [0.097408810215, 0.29335112354, 0.614673998089]
        for i in range(0, 3):
            self.assertAlmostEqual(self.bz.get_zt()['n'][800][4][i], ref[i])
        self.assertAlmostEqual(
            self.bz.get_zt(output='average', kl=0.5)['p'][700][2],
            0.0170001879916)
        self.assertAlmostEqual(
            self.bz.get_zt(output='average',
                           doping_levels=False,
                           relaxation_time=1e-15)[300][240],
            0.0041923533238348342)

        eigs = self.bz.get_zt(output='eigs', doping_levels=False)[700][65]
        ref_eigs = [
            0.082420053399668847, 0.29408035502671648, 0.40822061215079392
        ]
        for idx, val in enumerate(ref_eigs):
            self.assertAlmostEqual(eigs[idx], val, 5)

    def test_get_average_eff_mass(self):
        ref = [0.76045816788363574, 0.96181142990667101, 2.9428428773308628]
        for i in range(0, 3):
            self.assertAlmostEqual(
                self.bz.get_average_eff_mass()['p'][300][2][i], ref[i])
        ref = [1.1295783824744523, 1.3898454041924351, 5.2459984671977935]
        ref2 = [6.6648842712692078, 31.492540105738343, 37.986369302138954]
        for i in range(0, 3):
            self.assertAlmostEqual(
                self.bz.get_average_eff_mass()['n'][600][1][i], ref[i])
            self.assertAlmostEqual(
                self.bz.get_average_eff_mass(doping_levels=False)[300][200][i],
                ref2[i])
        ref = [[9.61811430e-01, -8.25159596e-19, -4.70319444e-19],
               [-8.25159596e-19, 2.94284288e+00, 3.00368916e-18],
               [-4.70319444e-19, 3.00368916e-18, 7.60458168e-01]]
        ref2 = [[2.79760445e+01, -2.39347589e-17, -1.36897140e-17],
                [-2.39347589e-17, 8.55969097e+01, 8.74169648e-17],
                [-1.36897140e-17, 8.74169648e-17, 2.21151980e+01]]

        for i in range(0, 3):
            for j in range(0, 3):
                self.assertAlmostEqual(
                    self.bz.get_average_eff_mass(
                        output='tensor')['p'][300][2][i][j], ref[i][j])
                self.assertAlmostEqual(
                    self.bz.get_average_eff_mass(
                        output='tensor', doping_levels=False)[300][500][i][j],
                    ref2[i][j])
        self.assertAlmostEqual(
            self.bz.get_average_eff_mass(output='average')['n'][300][2],
            1.53769093989)

    def test_get_carrier_concentration(self):
        self.assertAlmostEqual(
            self.bz.get_carrier_concentration()[300][39] / 1e22,
            6.4805156617179151, 4)
        self.assertAlmostEqual(
            self.bz.get_carrier_concentration()[300][693] / 1e15,
            -6.590800965604750, 4)

    def test_get_hall_carrier_concentration(self):
        self.assertAlmostEqual(
            self.bz.get_hall_carrier_concentration()[600][120] / 1e21,
            6.773394626767555, 4)
        self.assertAlmostEqual(
            self.bz.get_hall_carrier_concentration()[500][892] / 1e21,
            -9.136803845741777, 4)

    def test_get_symm_bands(self):
        structure = loadfn(
            os.path.join(test_dir, 'boltztrap/structure_mp-12103.json'))
        sbs = loadfn(os.path.join(test_dir, 'boltztrap/dft_bs_sym_line.json'))
        kpoints = [kp.frac_coords for kp in sbs.kpoints]
        labels_dict = {
            k: sbs.labels_dict[k].frac_coords
            for k in sbs.labels_dict
        }
        for kpt_line, labels_dict in zip([None, sbs.kpoints, kpoints],
                                         [None, sbs.labels_dict, labels_dict]):
            sbs_bzt = self.bz_bands.get_symm_bands(structure,
                                                   -5.25204548,
                                                   kpt_line=kpt_line,
                                                   labels_dict=labels_dict)
            self.assertAlmostEqual(len(sbs_bzt.bands[Spin.up]), 20)
            self.assertAlmostEqual(len(sbs_bzt.bands[Spin.up][1]), 143)

    # def test_check_acc_bzt_bands(self):
    #     structure = loadfn(os.path.join(test_dir,'boltztrap/structure_mp-12103.json'))
    #     sbs = loadfn(os.path.join(test_dir,'boltztrap/dft_bs_sym_line.json'))
    #     sbs_bzt = self.bz_bands.get_symm_bands(structure,-5.25204548)
    #     corr,werr_vbm,werr_cbm,warn = BoltztrapAnalyzer.check_acc_bzt_bands(sbs_bzt,sbs)
    #     self.assertAlmostEqual(corr[2],9.16851750e-05)
    #     self.assertAlmostEqual(werr_vbm['K-H'],0.18260273521047862)
    #     self.assertAlmostEqual(werr_cbm['M-K'],0.071552669981356981)
    #     self.assertFalse(warn)

    def test_get_complete_dos(self):
        structure = loadfn(
            os.path.join(test_dir, 'boltztrap/structure_mp-12103.json'))
        cdos = self.bz_up.get_complete_dos(structure, self.bz_dw)
        spins = list(cdos.densities.keys())
        self.assertIn(Spin.down, spins)
        self.assertIn(Spin.up, spins)
        self.assertAlmostEqual(
            cdos.get_spd_dos()[OrbitalType.p].densities[Spin.up][3134],
            43.839230100999991)
        self.assertAlmostEqual(
            cdos.get_spd_dos()[OrbitalType.s].densities[Spin.down][716],
            6.5383268000000001)

    def test_extreme(self):
        x = self.bz.get_extreme("seebeck")
        self.assertEqual(x["best"]["carrier_type"], "n")
        self.assertAlmostEqual(x["p"]["value"], 1255.365, 2)
        self.assertEqual(x["n"]["isotropic"], True)
        self.assertEqual(x["n"]["temperature"], 600)

        x = self.bz.get_extreme("kappa",
                                maximize=False,
                                min_temp=400,
                                min_doping=1E20)
        self.assertAlmostEqual(x["best"]["value"], 0.105, 2)
        self.assertAlmostEqual(x["n"]["value"], 0.139, 2)
        self.assertEqual(x["p"]["temperature"], 400)
        self.assertEqual(x["n"]["isotropic"], False)

    def test_to_from_dict(self):
        btr_dict = self.btr.as_dict()
        s = json.dumps(btr_dict)
        self.assertIsNotNone(s)
        self.assertIsNotNone(btr_dict['bs'])