Source code for dpgen.generator.lib.ele_temp

import os,dpdata,json
import numpy as np
import scipy.constants as pc
from pymatgen.io.vasp.inputs import Incar


[docs]class NBandsEsti(object): def __init__ (self, test_list): if type(test_list) is list: ele_t = [] vol = [] d_nbd = [] nbd = [] for ii in test_list: res = NBandsEsti._get_res(ii) ele_t.append(res['ele_temp']) vol.append(res['vol']) d_nbd.append(NBandsEsti._get_default_nbands(res)) nbd.append(res['nbands']) ele_t = np.array(ele_t) vol = np.array(vol) d_nbd = np.array(d_nbd) nbd = np.array(nbd) alpha = (nbd - d_nbd) / vol / ele_t**1.5 self.err = np.std(alpha) self.pref = np.average(alpha) # print(np.average(alpha), np.std(alpha), self.err/self.pref) # print((ele_t), vol, d_nbd, nbd, alpha) elif type(test_list) is str: with open(test_list) as fp: self.pref = float(fp.readline()) self.err = float(fp.readline()) else: raise RuntimeError('unknown input type ' + type(test_list))
[docs] def save(self, fname): with open(fname, 'w') as fp: fp.write(str(self.pref) + '\n') fp.write(str(self.err) + '\n')
[docs] def predict(self, target_dir, tolerance = 0.5): res = NBandsEsti._get_res(target_dir) ele_t=(res['ele_temp']) vol=(res['vol']) d_nbd=(NBandsEsti._get_default_nbands(res)) nbd=(res['nbands']) esti = (self.pref + tolerance*self.err) * ele_t**1.5 * vol + d_nbd return int(esti)+1
@classmethod def _get_res(self, res_dir): res = {} sys = dpdata.System(os.path.join(res_dir, 'POSCAR')) res['natoms'] = (sys['atom_numbs']) res['vol'] = np.linalg.det(sys['cells'][0]) res['nvalence'] = (self._get_potcar_nvalence(os.path.join(res_dir, 'POTCAR'))) res['ele_temp'] = self._get_incar_ele_temp(os.path.join(res_dir, 'INCAR')) * pc.electron_volt / pc.Boltzmann res['nbands'] = self._get_incar_nbands(os.path.join(res_dir, 'INCAR')) return res @classmethod def _get_default_nbands(self, res): ret = 0 for ii,jj in zip(res['natoms'], res['nvalence']): ret += ii * jj // 2 + ii // 2 + 2 return ret @classmethod def _get_potcar_nvalence(self, fname): with open(fname) as fp: pot_str = fp.read().split('\n') head_idx = [] for idx,ii in enumerate(pot_str): if ('PAW_' in ii) and ('TITEL' not in ii): head_idx.append(idx) res = [] for ii in head_idx: res.append(float(pot_str[ii+1])) return res @classmethod def _get_incar_ele_temp(self, fname): incar = Incar.from_file(fname) return incar['SIGMA'] @classmethod def _get_incar_nbands(self, fname): incar = Incar.from_file(fname) return incar.get('NBANDS')