Source code for dpgen.generator.lib.ele_temp

import os

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


[docs] class NBandsEsti: def __init__(self, test_list): if isinstance(test_list, 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 isinstance(test_list, 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")