Source code for dpgen2.fp.vasp_input

import numpy as np
import dpdata
from pathlib import Path
from typing import (
    Optional,
    Tuple, 
    List, 
    Set, 
    Dict,
    Union,
)
from dargs import (
    dargs, 
    Argument, 
    Variant, 
    ArgumentEncoder,
)

[docs]class VaspInputs(): def __init__( self, kspacing : Union[float, List[float]], incar : str, pp_files : Dict[str, str], kgamma : bool = True, ): """ Parameters ---------- kspacing : Union[float, List[float]] The kspacing. If it is a number, then three directions use the same ksapcing, otherwise it is a list of three numbers, specifying the kspacing used in the x, y and z dimension. incar: str A template INCAR file. pp_files : Dict[str,str] The potcar files for the elements. For example { "H" : "/path/to/POTCAR_H", "O" : "/path/to/POTCAR_O", } kgamma : bool K-mesh includes the gamma point """ self.kspacing = kspacing self.kgamma = kgamma self.incar_from_file(incar) self.potcars_from_file(pp_files) @property def incar_template(self): return self._incar_template @property def potcars(self): return self._potcars
[docs] def incar_from_file( self, fname : str, ): self._incar_template = Path(fname).read_text()
[docs] def potcars_from_file( self, dict_fnames : Dict[str,str], ): self._potcars = {} for kk,vv in dict_fnames.items(): self._potcars[kk] = Path(vv).read_text()
[docs] def make_potcar( self, atom_names, ) -> str: potcar_contents = [] for nn in atom_names: potcar_contents.append(self._potcars[nn]) return "".join(potcar_contents)
[docs] def make_kpoints( self, box : np.ndarray, ) -> str: return make_kspacing_kpoints(box, self.kspacing, self.kgamma)
[docs] @staticmethod def args(): doc_pp_files = 'The pseudopotential files set by a dict, e.g. {"Al" : "path/to/the/al/pp/file", "Mg" : "path/to/the/mg/pp/file"}' doc_incar = "The path to the template incar file" doc_kspacing = "The spacing of k-point sampling. `ksapcing` will overwrite the incar template" doc_kgamma = "If the k-mesh includes the gamma point. `kgamma` will overwrite the incar template" return [ Argument("incar", str, optional=False, doc=doc_pp_files), Argument("pp_files", dict, optional=False, doc=doc_pp_files), Argument("kspacing", float, optional=False, doc=doc_kspacing), Argument("kgamma", bool, optional=True, default=True, doc=doc_kgamma), ]
[docs] @staticmethod def normalize_config(data = {}, strict=True): ta = VaspInputs.args() base = Argument("base", dict, ta) data = base.normalize_value(data, trim_pattern="_*") base.check_value(data, strict=strict) return data
[docs]def make_kspacing_kpoints(box, kspacing, kgamma) : if type(kspacing) is not list: kspacing = [kspacing, kspacing, kspacing] box = np.array(box) rbox = _reciprocal_box(box) kpoints = [max(1,(np.ceil(2 * np.pi * np.linalg.norm(ii) / ks).astype(int))) for ii,ks in zip(rbox,kspacing)] ret = _make_vasp_kpoints(kpoints, kgamma) return ret
def _make_vasp_kp_gamma(kpoints): ret = "" ret += "Automatic mesh\n" ret += "0\n" ret += "Gamma\n" ret += "%d %d %d\n" % (kpoints[0], kpoints[1], kpoints[2]) ret += "0 0 0\n" return ret def _make_vasp_kp_mp(kpoints): ret = "" ret += "K-Points\n" ret += "0\n" ret += "Monkhorst Pack\n" ret += "%d %d %d\n" % (kpoints[0], kpoints[1], kpoints[2]) ret += "0 0 0\n" return ret def _make_vasp_kpoints (kpoints, kgamma = False) : if kgamma : ret = _make_vasp_kp_gamma(kpoints) else : ret = _make_vasp_kp_mp(kpoints) return ret def _reciprocal_box(box) : rbox = np.linalg.inv(box) rbox = rbox.T return rbox