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
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()}
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())
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
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
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")
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
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
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)
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)
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)
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)
def transport_run(self,doping=[],output_dir='./'): BoltztrapRunner(self.bs,self.nelec,doping=doping,symprec=0.1).run(output_dir)
def band_interpolate(self,output_dir='./'): BoltztrapRunner(self.bs,self.nelec,run_type='BANDS').run(output_dir)
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])
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)
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'])
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
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)
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'])