Source code for jarvis.tasks.vasp.vasp

"""Modules for high-throughput VASP calculations."""

from jarvis.io.vasp.outputs import Outcar, Vasprun
from jarvis.io.vasp.inputs import Poscar, Incar, Potcar
from jarvis.db.jsonutils import loadjson
from jarvis.core.kpoints import Kpoints3D as Kpoints
from jarvis.analysis.structure.spacegroup import Spacegroup3D

# from jarvis.core.utils import update_dict
import subprocess
import json
import os
import glob
from jarvis.io.wanniertools.inputs import WTin
from jarvis.io.wannier.inputs import Wannier90win
from jarvis.io.wannier.outputs import Wannier90eig
import shutil
from jarvis.io.vasp.inputs import find_ldau_magmom, add_ldau_incar
from collections import OrderedDict
from jarvis.core.kpoints import Kpoints3D
from jarvis.analysis.magnetism.magmom_setup import MagneticOrdering


[docs]def write_vaspjob(pyname="job.py", job_json=""): """Write template job.py with VaspJob.to_dict() job.json.""" f = open(pyname, "w") f.write("from jarvis.tasks.vasp.vasp import VaspJob\n") f.write("from jarvis.db.jsonutils import loadjson\n") f.write('d=loadjson("' + str(job_json) + '")\n') f.write("v=VaspJob.from_dict(d)\n") f.write("v.runjob()\n") f.close()
[docs]def write_jobfact( pyname="job.py", job_json="", input_arg="v.soc_spillage()\n" ): """Write template job.py with JobFactory.to_dict() job.json.""" f = open(pyname, "w") f.write("from jarvis.tasks.vasp.vasp import JobFactory\n") f.write("from jarvis.db.jsonutils import loadjson\n") f.write('d=loadjson("' + str(job_json) + '")\n') f.write("v=JobFactory.from_dict(d)\n") f.write(input_arg) f.close()
[docs]def write_jobfact_optb88vdw(pyname="job.py", job_json=""): """Write template job.py with JobFactory.to_dict() job.json.""" f = open(pyname, "w") f.write("from jarvis.tasks.vasp.vasp import JobFactory\n") f.write("from jarvis.db.jsonutils import loadjson\n") f.write('d=loadjson("' + str(job_json) + '")\n') f.write("v=JobFactory.from_dict(d)\n") f.write("v.all_optb88vdw_calcs()\n") f.close()
# def add_ldau_incar(use_incar_dict={}, Uval=2):
[docs]class JobFactory(object): """Provide sets of VASP calculations.""" def __init__( self, name="Jobs", poscar=None, use_incar_dict={}, vasp_cmd="", pot_type="POT_GGA_PAW_PBE", copy_files=[], attempts=5, stderr_file="std_err.txt", output_file="vasp.out", optional_params={ "kppa": 1000, "extension": "SCAN", "encut": 500, "kpleng": 20, "line_density": 20, "wann_cmd": "~/bin/wannier90.x wannier90", "wt_cmd": "~/bin/wt.x", "run_wannier": True, "ldau": False, "Uval": 2.0, }, steps=[ "ENCUT", "KPLEN", "RELAX", "BANDSTRUCT", "LOPTICS", "MBJOPTICS", "ELASTIC", "SPILLAGE", "EFG", "MAGORDER", "DFPT", "RAMANINTS", "SHG", ], ): """ Provide generic class for running variations of VASP calculations. Minimum arguments given below. Args: name : generic name use_incar_dict : dictionary with INCAR parameters that would be repreated pot_type : pseudopotential type vasp_cmd: vasp executable """ # TODO: Make JobFactory a superclass of VaspJob class self.name = name self.use_incar_dict = use_incar_dict # if ldau: # if 'LSORBIT' in use_incar_dict # and use_incar_dict['LSORBIT']=='.TRUE.': # info_ldau = # find_ldau_magmom(U=Uval,atoms=poscar.atoms,lsorbit=True) # else: # info_ldau # = find_ldau_magmom(U=Uval,atoms=poscar.atoms,lsorbit=False) # tmp = update_dict(use_incar_dict,info_ldau) # use_incar_dict = tmp self.pot_type = pot_type self.vasp_cmd = vasp_cmd self.mat = poscar self.copy_files = copy_files self.attempts = attempts self.stderr_file = stderr_file self.output_file = output_file self.optional_params = optional_params self.steps = steps
[docs] def step_flow(self): """Asiimilate number of steps as legos for a workflow.""" for i in self.steps: if i == "ENCUT": encut = self.converg_encut(mat=self.mat) self.optional_params["encut"] = encut if i == "KPLEN": length = self.converg_kpoint(mat=self.mat) self.optional_params["kpleng"] = length if i == "RELAX": energy, contcar_path = self.optimize_geometry( mat=self.mat, encut=encut, length=length ) vrun = Vasprun(contcar_path.replace("CONTCAR", "vasprun.xml")) chg_path = contcar_path.replace("CONTCAR", "CHGCAR") nbands = int(vrun.all_input_parameters["NBANDS"]) self.optional_params["chg_path"] = chg_path self.optional_params["nbands"] = nbands self.mat = Poscar.from_file(contcar_path) if i == "BANDSTRUCT": enB, contcB = self.band_structure( mat=self.mat, encut=self.optional_params["encut"], line_density=self.optional_params["line_density"], nbands=2 * nbands, copy_prev_chgcar=chg_path, ) if i == "OPTICS": enL, contcL = self.loptics( mat=self.mat, encut=self.optional_params["encut"], nbands=2 * self.optional_params["nbands"], length=self.optional_params["kpleng"], ) if i == "MBJOPTICS": enM, contcM = self.mbj_loptics( mat=self.mat, encut=self.optional_params["encut"], nbands=2 * nbands, length=length, ) if i == "ELASTIC": enE, contcE = self.elastic( mat=self.mat, encut=self.optional_params["encut"], nbands=2 * self.optional_params["nbands"], length=self.optional_params["kpleng"], ) if i == "SPILLAGE": self.soc_spillage( mat=self.mat, # ldau=self.optional_params["ldau"], # Uval=self.optional_params["Uval"], encut=self.optional_params["encut"], nbands=None, kppa=self.optional_params["kppa"], ) if i == "EFG": enE, contcE = self.efg( mat=self.mat, encut=self.optional_params["encut"], length=self.optional_params["kpleng"], ) if i == "DFPT": enE, contcE = self.dfpt( mat=self.mat, encut=self.optional_params["encut"], length=self.optional_params["kpleng"], ) if i == "MAGORDER": enE, contcE = self.magorder( encut=self.optional_params["encut"], length=self.optional_params["kpleng"], )
[docs] def all_optb88vdw_calcs(self): """Use for OptB88vdW based HT.""" incs = GenericIncars().optb88vdw() return self.workflow(generic_incar=incs)
[docs] def all_pbe_calcs(self): """Use for PBE based HT.""" incs = GenericIncars().pbe() return self.workflow(generic_incar=incs)
[docs] def all_scan_calcs(self): """Use for SCAN based HT.""" incs = GenericIncars().scan() return self.workflow(generic_incar=incs)
[docs] def all_lda_calcs(self): """Use for LDA based HT.""" incs = GenericIncars().lda() return self.workflow(generic_incar=incs)
[docs] def workflow(self, generic_incar=""): """ Use for functional based high-throughput calculations. This will converge k-points, cut-offs, and then carry several property calculations. Args: mat : Poscar object """ self.steps = ( [ "ENCUT", "KPLEN", "RELAX", "BANDSTRUCT", "LOPTICS", "MBJOPTICS", "ELASTIC", "SPILLAGE", "EFG", "MAGORDER", "DFPT", ], ) self.step_flow()
[docs] def magorder(self, min_configs=3, length=20): """Determine structures for FM, AFM, FiM magnetic ordering.""" incar_dict = self.use_incar_dict.copy() ldau = self.optional_params["ldau"] data = { "ENCUT": 1.3 * float(self.optional_params["encut"]), "NEDOS": 5000, "ISIF": 3, "ISPIN": 2, "IBRION": 6, "LCHARG": ".FALSE.", } incar_dict.update(data) inc = Incar.from_dict(incar_dict) symm_list, ss = MagneticOrdering(atoms=self.atoms).get_minimum_configs( min_configs=3 ) for i in range(len(symm_list)): if ldau: tmp = add_ldau_incar( use_incar_dict=incar_dict, atoms=ss, Uval=self.optional_params["Uval"], ) incar_dict = tmp info_ldau = find_ldau_magmom(atoms=ss) inc_tmp = inc.update(info_ldau) inc1 = inc_tmp.update( {"MAGMOM": " ".join(map(str, symm_list[i]))} ) else: inc_tmp = inc inc1 = inc_tmp.update( {"MAGMOM": " ".join(map(str, symm_list[i]))} ) pos = Poscar(ss) name = "Mag-" + "_" + str(i) # pot = Potcar(elements=ss.elements) kp = Kpoints3D().automatic_length_mesh( lattice_mat=ss.lattice_mat, length=20 ) # cwd = str(os.getcwd()) sub_dir = name if not os.path.exists(sub_dir): os.makedirs(sub_dir) os.chdir(sub_dir) VaspJob( poscar=pos, incar=inc1, kpoints=kp, pot_type=self.pot_type, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=name, ).runjob()
[docs] def elastic( self, mat=None, encut=None, nbands=None, potim=0.015, npar=None, length=20, ): """ Use for elastic property calculations using IBRION = 6. Enforces conventional standard structure. Args: mat : Poscar object encut : Plane-wave cut-off, 1.3 times will be used nbands : number of bands, generally high-value recommended npar : NPAR tag, see VASP manual, set it as number of cores length : K-points in length unit """ incar_dict = self.use_incar_dict.copy() cvn = Spacegroup3D(mat.atoms).conventional_standard_structure comment = mat.comment p = Poscar(cvn, comment=comment) if npar is not None: incar_dict.update({"NPAR": npar}) if nbands is not None: nbands = int(nbands * 3) incar_dict.update({"NBANDS": nbands}) data = { "ENCUT": 1.3 * float(self.optional_params["encut"]), "NEDOS": 5000, "ISIF": 3, "POTIM": potim, "ISPIN": 2, "IBRION": 6, "LCHARG": ".FALSE.", } incar_dict.update(data) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().automatic_length_mesh( lattice_mat=p.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) en, contcar = VaspJob( poscar=p, incar=incar, pot_type=self.pot_type, kpoints=kpoints, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=str("MAIN-ELASTIC-") + str(p.comment.split()[0]), ).runjob() return en, contcar
[docs] def efg(self, mat=None, encut=None, nbands=None, length=20): """ Use for electric field gradient calculation. Args: mat : Poscar object encut : Plane-wave cut-off, 1.3 times will be used nbands : number of bands, increased to threee times length : K-points in length unit """ # incar = self.use_incar_dict incar_dict = self.use_incar_dict.copy() if nbands is not None: nbands = int(nbands * 3) incar_dict.update({"NBANDS": nbands}) data = { "ENCUT": encut, "NEDOS": 5000, "NELM": 500, "LORBIT": 11, "ISPIN": 2, "LEFG": ".TRUE.", "SIGMA": 0.1, "IBRION": 1, "LCHARG": ".FALSE.", } incar_dict.update(data) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-LEFG-") + str(mat.comment.split()[0]), ).runjob() return en, contcar
[docs] def dfpt(self, mat=None, encut=None, nbands=None, length=20): """ Use for density functional perturbation theory calculation. Args: mat : Poscar object encut : Plane-wave cut-off, 1.3 times will be used nbands : number of bands, increased to threee times length : K-points in length unit """ # incar = self.use_incar_dict incar_dict = self.use_incar_dict.to_dict().copy() if nbands is not None: nbands = int(nbands * 3) incar_dict.update({"NBANDS": nbands}) data = { "ENCUT": encut, "NEDOS": 5000, "NELM": 500, "LORBIT": 11, "ISPIN": 2, "LEPSION": ".TRUE.", "SIGMA": 0.1, "IBRION": 1, "LCHARG": ".FALSE.", } incar_dict.update(data) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-LEPSLON-") + str(mat.comment.split()[0]), ).runjob() return en, contcar
[docs] def mbj_loptics(self, mat=None, encut=None, nbands=None, length=20): """ Use for TBmBJ meta-GGA calculation. Args: mat : Poscar object encut : Plane-wave cut-off, 1.3 times will be used nbands : number of bands, increased to threee times length : K-points in length unit """ # incar = self.use_incar_dict incar_dict = self.use_incar_dict.copy() if nbands is not None: nbands = int(nbands * 3) incar_dict.update({"NBANDS": nbands}) data = { "ENCUT": encut, "NEDOS": 5000, "NELM": 500, "LORBIT": 11, "ISPIN": 2, "METAGGA": "MBJ", "SIGMA": 0.1, "ISYM": 0, "LOPTICS": ".TRUE.", "IBRION": 1, "LCHARG": ".FALSE.", } incar_dict.update(data) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-MBJ-") + str(mat.comment.split()[0]), ).runjob() return en, contcar
[docs] def soc_spillage( self, mat=None, encut=None, nbands=None, kppa=1000, leng=None ): """ Use for SOC spillage calculation. Args: mat : Poscar object encut : Plane-wave cut-off, 1.3 times will be used nbands : number of bands, increased to threee times kppa : K-points in kpoints per atom unit """ incar_dict = self.use_incar_dict.copy() if nbands is not None: nbands = int(nbands * 3) incar_dict.update({"NBANDS": nbands}) ldau = self.optional_params["ldau"] data = { "ENCUT": encut, "NEDOS": 5000, "NELM": 600, "LORBIT": 11, "ISPIN": 2, "IBRION": 2, "NPAR": 4, "NSW": 60, "EDIFF": "1E-6", "SIGMA": 0.01, "LCHARG": ".TRUE.", "LWAVE": ".TRUE.", } incar_dict.update(data) if ldau: tmp = add_ldau_incar( use_incar_dict=incar_dict, atoms=mat.atoms, Uval=self.optional_params["Uval"], ) incar_dict = tmp incar = Incar.from_dict(incar_dict) kpoints = Kpoints().kpoints_per_atom(atoms=mat.atoms, kppa=kppa) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-MAGSCF-") + str(self.optional_params["extension"]) + str(mat.comment.split()[0]), ).runjob() data = { "ENCUT": encut, "EDIFF": "1E-6", "NEDOS": 5000, "NELM": 600, "LORBIT": 11, "ICHARG": 11, "NSW": 0, "ISPIN": 2, "IBRION": 2, "NPAR": 4, "SIGMA": 0.01, "LCHARG": ".TRUE.", "LWAVE": ".TRUE.", } incar_dict = self.use_incar_dict.copy() incar_dict.update(data) if ldau: tmp = add_ldau_incar( use_incar_dict=incar_dict, atoms=mat.atoms, Uval=self.optional_params["Uval"], ) incar_dict = tmp incar = Incar.from_dict(incar_dict) kpoints = Kpoints().kpath( mat.atoms, line_density=self.optional_params["line_density"] ) tmp = self.copy_files chg = contcar.replace("CONTCAR", "CHGCAR") tmp.append(chg) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=tmp, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-MAGSCFBAND-") + str(self.optional_params["extension"]) + str(mat.comment.split()[0]), ).runjob() incar_dict = self.use_incar_dict.copy() if nbands is not None: nbands = int(nbands * 3) incar_dict.update({"NBANDS": nbands}) data = { "ENCUT": encut, "NEDOS": 5000, "EDIFF": "1E-6", "NELM": 600, "LORBIT": 11, "NSW": 60, "NPAR": 4, "LSORBIT": ".TRUE.", "IBRION": 2, "SIGMA": 0.01, "LCHARG": ".TRUE.", "LWAVE": ".TRUE.", } incar_dict.update(data) if ldau: tmp1 = add_ldau_incar( use_incar_dict=incar_dict, lsorbit=True, Uval=self.optional_params["Uval"], atoms=mat.atoms, ) incar_dict = tmp1 incar = Incar.from_dict(incar_dict) kpoints = Kpoints().kpoints_per_atom(atoms=mat.atoms, kppa=kppa) # TODO: Find nwan, exclude, sum them up and add 10% extra en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=tmp, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-SOCSCF-") + str(mat.comment.split()[0]), ).runjob() data = { "ENCUT": encut, "NEDOS": 5000, "EDIFF": "1E-6", "NELM": 600, "LORBIT": 11, "ICHARG": 11, "IBRION": 2, "NSW": 0, "SIGMA": 0.01, "NPAR": 4, "LSORBIT": ".TRUE.", "LCHARG": ".TRUE.", "LWAVE": ".TRUE.", } incar_dict = self.use_incar_dict.copy() incar_dict.update(data) if ldau: tmp1 = add_ldau_incar( use_incar_dict=incar_dict, lsorbit=True, Uval=self.optional_params["Uval"], atoms=mat.atoms, ) incar_dict = tmp1 incar = Incar.from_dict(incar_dict) kpoints = Kpoints().kpath( mat.atoms, line_density=self.optional_params["line_density"] ) tmp = self.copy_files chg = contcar.replace("CONTCAR", "CHGCAR") tmp.append(chg) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=tmp, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-SOCSCFBAND-") + str(self.optional_params["extension"]) + str(mat.comment.split()[0]), ).runjob() dir = str(os.getcwd()) + str("/MAIN-*") if self.optional_params["run_wannier"]: for i in glob.glob(dir): if ( os.path.isdir(i) and "BAND" not in i and "WANN" not in i and "SOC" in i ): tmp = i.split("MAIN-") wann_name = ( str(tmp[0]) + str("MAIN-WANN-") + str(self.optional_params["extension"]) + str(tmp[1]) ) if not os.path.isdir(wann_name): os.makedirs(wann_name) cmd = str("rsync ") + str(i) + str("/* ") + str(wann_name) os.system(cmd) os.chdir(wann_name) v = "" run = str(i) + str("/vasprun.xml") out = Outcar(str(i) + str("/OUTCAR")) v = Vasprun(run) efermi = v.efermi nbands = ( out.nbands ) # int(v.all_input_parameters["NBANDS"]) strt = v.all_structures[-1] nwan, exclude = Wannier90win( struct=strt, efermi=efermi, soc=True ).write_win() cmd = "cp win.input wannier90.win" os.system(cmd) # Add 10 % extra bands tmp_bands = int(1.1 * (nwan + exclude)) if tmp_bands > nbands: new_nbands = tmp_bands if nbands < new_nbands: nbands = new_nbands os.system(cmd) data = dict( PREC="Accurate", ALGO="None", NBANDS=nbands, LSORBIT=".TRUE.", ISMEAR=0, NSW=0, NELM=1, SIGMA=0.01, LWANNIER90=".TRUE.", LWRITE_MMN_AMN=".TRUE.", NEDOS=5000, LORBIT=11, LWAVE=".FALSE.", LCHARG=".FALSE.", ENCUT=encut, ) incar_dict = self.use_incar_dict.copy() incar_dict.update(data) if ldau: tmp1 = add_ldau_incar( use_incar_dict=incar_dict, Uval=self.optional_params["Uval"], atoms=strt, ) incar_dict = tmp1 incar = Incar.from_dict(incar_dict) incar.write_file("INCAR") print("directory", os.getcwd()) vasp_cmd = self.vasp_cmd if "vasp_std" in self.vasp_cmd: vasp_cmd = self.vasp_cmd.replace("std", "ncl") cmd = vasp_cmd os.system(cmd) neigs = Wannier90eig("wannier90.eig").neigs() tmp = neigs Wannier90win(struct=strt, efermi=efermi).write_hr_win( nbands=tmp ) cmd = "cp hr_wannier.win wannier90.win" os.system(cmd) cmd = self.optional_params["wann_cmd"] os.system(cmd) nelect = Outcar("OUTCAR").nelect WTin( atoms=strt, wannierout="wannier90.wout", efermi=efermi, nelect=nelect, exclude=exclude, nwan=nwan, ).write_wt_in() cmd = self.optional_params["wt_cmd"] # "/users/knc6/Software/wannier_tools/bin/wt.x" os.system(cmd) # Make sure wanniertools is the last step in the workflow return en, contcar
[docs] def loptics(self, mat=None, encut=None, nbands=None, length=20): """ Use in linear-optics calculations. Args: mat : Poscar object encut : Plane-wave cut-off, 1.3 times will be used nbands : number of bands, increased to threee times length : K-points in length unit """ # incar = self.use_incar_dict incar_dict = self.use_incar_dict.copy() if nbands is not None: nbands = int(nbands * 3) incar_dict.update({"NBANDS": nbands}) data = { "ENCUT": encut, "NEDOS": 5000, "NELM": 500, "LORBIT": 11, "ISPIN": 2, "LOPTICS": ".TRUE.", "IBRION": 1, "LCHARG": ".FALSE.", } incar_dict.update(data) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) en, contcar = VaspJob( poscar=mat, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, incar=incar, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-OPTICS-") + str(mat.comment.split()[0]), ).runjob() return en, contcar
[docs] def band_structure( self, mat=None, encut=None, line_density=20, nbands=None, copy_prev_chgcar=None, ): """ Use in band-structure calculations. Args: mat : Poscar object encut : Plane-wave cut-off, 1.3 times will be used nbands : number of bands, increased to threee times line_density : number of k-points between two high-symmetry k-points copy_prev_chgcar : path of CHGCAR file for Non-SCF step """ # incar = self.use_incar_dict incar_dict = self.use_incar_dict.copy() copy_files = self.copy_files # tmp = self.copy_files if copy_prev_chgcar is not None: copy_files.append(copy_prev_chgcar) if nbands is not None: nbands = int(nbands * 1.3) incar_dict.update({"NBANDS": nbands}) data = { "ENCUT": encut, "NEDOS": 5000, "NELM": 500, "LORBIT": 11, "ISPIN": 2, "IBRION": 1, "LCHARG": ".FALSE.", } incar_dict.update(data) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().kpath(self.mat.atoms, line_density=line_density) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=copy_files, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-BAND-") + str(mat.comment.split()[0]), ).runjob() return en, contcar
[docs] def optimize_geometry(self, mat=None, encut=None, length=None): """ Use in optimizing lattice-parameter and internal psotions. Args: mat : Poscar object encut : Plane-wave cut-off length : K-points in length unit """ incar_dict = self.use_incar_dict.copy() data = { "ENCUT": encut, "EDIFFG": -1e-3, "ISIF": 3, "NEDOS": 5000, "NSW": 500, "NELM": 500, "LORBIT": 11, "LVTOT": ".TRUE.", "LVHAR": ".TRUE.", "ISPIN": 2, "LCHARG": ".TRUE.", } incar_dict.update(data) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) en, contcar = VaspJob( poscar=mat, incar=incar, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, pot_type=self.pot_type, kpoints=kpoints, jobname=str("MAIN-RELAX-") + str(mat.comment), ).runjob() return en, contcar
[docs] def converg_encut( self, encut=500, mat=None, starting_length=10, tol=0.001 ): """ Provide function to converg plane-wave cut-off. Args: encut: intial cutoff mat: Poscar object Returns: encut: converged cut-off """ pot_type = self.pot_type en1 = -10000 encut1 = encut convg_encut1 = False convg_encut2 = False incar_dict = self.use_incar_dict.copy() while not convg_encut2 and not convg_encut1: # while convg_encut1 !=True and convg_encut2 !=True: # tol = 0.001 # change 0.001 encut_list = [] encut_list.append(encut) length = starting_length encut1 = encut + 50 # incar_dict = self.use_incar_dict # print ('incar_dict',incar_dict) incar_dict.update({"ENCUT": encut}) # print (use_incar_dict) incar = Incar.from_dict(incar_dict) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) print( "running smart_converge for", str(mat.comment) + str("-") + str("ENCUT") + str("-") + str(encut), ) en2, contc = VaspJob( poscar=mat, incar=incar, pot_type=pot_type, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, kpoints=kpoints, jobname=str("ENCUT") + str(mat.comment) + str("-") + str(encut), ).runjob() while abs(en2 - en1) > tol: en1 = en2 encut1 = encut + 50 encut_list.append(encut) print("Incrementing encut", encut) incar_dict.update({"ENCUT": encut1}) incar = Incar.from_dict(incar_dict) print( "running smart_converge for", str(mat.comment) + str("-") + str("ENCUT") + str("-") + str(encut), ) en2, contc = VaspJob( poscar=mat, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, incar=incar, pot_type=pot_type, kpoints=kpoints, jobname=str("ENCUT") + str(mat.comment) + str("-") + str(encut), ).runjob() convg_encut1 = True # Some extra points to check print("Some extra points to check for ENCUT") encut2 = encut1 + 50 incar_dict["ENCUT"] = encut2 incar = Incar.from_dict(incar_dict) en3, contc = VaspJob( vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, poscar=mat, incar=incar, pot_type=pot_type, kpoints=kpoints, jobname=str("ENCUT") + str(mat.comment) + str("-") + str(encut2), ).runjob() encut3 = encut2 + 50 incar_dict["ENCUT"] = encut3 incar = Incar.from_dict(incar_dict) en4, contc = VaspJob( poscar=mat, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, incar=incar, pot_type=pot_type, kpoints=kpoints, jobname=str("ENCUT") + str(mat.comment) + str("-") + str(encut3), ).runjob() encut4 = encut3 + 50 incar_dict["ENCUT"] = encut4 incar = Incar.from_dict(incar_dict) en5, contc = VaspJob( poscar=mat, incar=incar, pot_type=pot_type, kpoints=kpoints, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=str("ENCUT") + str(mat.comment) + str("-") + str(encut4), ).runjob() encut5 = encut4 + 50 incar_dict["ENCUT"] = encut5 incar = Incar.from_dict(incar_dict) en6, contc = VaspJob( poscar=mat, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, pot_type=pot_type, incar=incar, kpoints=kpoints, jobname=str("ENCUT") + str(mat.comment) + str("-") + str(encut5), ).runjob() encut6 = encut5 + 50 incar_dict["ENCUT"] = encut6 incar = Incar.from_dict(incar_dict) en7, contc = VaspJob( poscar=mat, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, pot_type=pot_type, incar=incar, kpoints=kpoints, jobname=str("ENCUT") + str(mat.comment) + str("-") + str(encut6), ).runjob() if ( abs(en3 - en2) > tol or abs(en4 - en2) > tol or abs(en5 - en2) > tol or abs(en6 - en2) > tol or abs(en7 - en2) > tol ): en1 = en3 encut = encut1 fen = open("EXTRA_ENCUT", "w") line = str("Extra ENCUT needed ") + str(encut) + "\n" fen.write(line) fen.close() else: print("ENCUT convergence achieved for ", mat.comment, encut) convg_encut2 = True return encut
[docs] def converg_kpoint(self, length=0, mat=None, encut=500, tol=0.001): """ Provide function to converg K-points. Args: lenght: K-point line density mat: Poscar object with structure information Returns: length1: K-point line density """ pot_type = self.pot_type en1 = -10000 convg_kp1 = False convg_kp2 = False length1 = length kp_list = [] while not convg_kp2 and not convg_kp1: # while convg_kp1 !=True and convg_kp2 !=True: incar_dict = self.use_incar_dict.copy() incar_dict.update({"ENCUT": encut}) incar = Incar.from_dict(incar_dict) # incar_dict["ENCUT"]= encut length1 = length1 + 5 print("Incrementing length", length1) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] if mesh not in kp_list: kp_list.append(mesh) en2, contc = VaspJob( poscar=mat, incar=incar, pot_type=pot_type, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, kpoints=kpoints, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length1), ).runjob() while abs(en2 - en1) > tol: en1 = en2 print("Incrementing length", length1) while mesh in kp_list: length1 = length1 + 5 # Assuming you are not super unlucky # kpoints = Auto_Kpoints(mat=mat, length=length1) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length1 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length1 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] if mesh not in kp_list: kp_list.append(mesh) en2, contc = VaspJob( poscar=mat, incar=incar, pot_type=pot_type, kpoints=kpoints, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length1), ).runjob() else: length1 = length1 + 5 # Assuming you are not super unlucky # kpoints = Auto_Kpoints(mat=mat, length=length1) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length1 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] kp_list.append(mesh) en2, contc = VaspJob( mat=mat, incar=incar, kpoints=kpoints, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length1), ).runjob() convg_kp1 = True # Some extra points to check print("Some extra points to check for KPOINTS") length3 = length1 + 5 # kpoints = Auto_Kpoints(mat=mat, length=length3) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length3 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] kp_list.append(mesh) en3, contc = VaspJob( poscar=mat, pot_type=pot_type, incar=incar, kpoints=kpoints, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length3), ).runjob() length4 = length3 + 5 # kpoints = Auto_Kpoints(mat=mat, length=length4) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length4 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] kp_list.append(mesh) en4, contc = VaspJob( poscar=mat, pot_type=pot_type, incar=incar, kpoints=kpoints, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length4), ).runjob() length5 = length4 + 5 # kpoints = Auto_Kpoints(mat=mat, length=length5) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length5 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] kp_list.append(mesh) en5, contc = VaspJob( poscar=mat, incar=incar, pot_type=pot_type, kpoints=kpoints, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length5), ).runjob() length6 = length5 + 5 # kpoints = Auto_Kpoints(mat=mat, length=length6) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length6 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] kp_list.append(mesh) en6, contc = VaspJob( poscar=mat, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, incar=incar, pot_type=pot_type, kpoints=kpoints, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length6), ).runjob() length7 = length6 + 5 # kpoints = Auto_Kpoints(mat=mat, length=length7) kpoints = Kpoints().automatic_length_mesh( lattice_mat=mat.atoms.lattice_mat, length=length7 ) # Auto_Kpoints(mat=mat, length=length) mesh = kpoints.kpts[0] kp_list.append(mesh) en7, contc = VaspJob( poscar=mat, vasp_cmd=self.vasp_cmd, output_file=self.output_file, stderr_file=self.stderr_file, copy_files=self.copy_files, attempts=self.attempts, incar=incar, pot_type=pot_type, kpoints=kpoints, jobname=str("KPOINTS") + str(mat.comment) + str("-") + str(length7), ).runjob() if ( abs(en3 - en2) > tol or abs(en4 - en2) > tol or abs(en5 - en2) > tol or abs(en6 - en2) > tol or abs(en7 - en2) > tol ): fkp = open("EXTRA_KPOINTS", "w") line = str("Extra KPOINTS needed ") + str(length1) + "\n" fkp.write(line) line = ( str("en2 length1 ") + str(" ") + str(en2) + str(" ") + str(length1) + "\n" ) fkp.write(line) line = ( str("en3 length3 ") + str(" ") + str(en3) + str(" ") + str(length3) + "\n" ) fkp.write(line) line = ( str("en4 length4 ") + str(" ") + str(en4) + str(" ") + str(length4) + "\n" ) fkp.write(line) line = ( str("en5 length5 ") + str(" ") + str(en5) + str(" ") + str(length5) + "\n" ) fkp.write(line) fkp.close() en1 = en3 length1 = length3 else: print( "KPOINTS convergence achieved for ", mat.comment, length1, ) convg_kp2 = True return length1
[docs] @classmethod def from_dict(self, d={}): """Load from dictionary.""" job = JobFactory( use_incar_dict=d["use_incar_dict"], pot_type=d["pot_type"], vasp_cmd=d["vasp_cmd"], copy_files=d["copy_files"], attempts=d["attempts"], stderr_file=d["stderr_file"], output_file=d["output_file"], poscar=Poscar.from_dict(d["poscar"]), optional_params=d["optional_params"], steps=d["steps"], ) return job
[docs] def to_dict(self): """Convert to dictionary.""" d = OrderedDict() d["name"] = self.name d["use_incar_dict"] = self.use_incar_dict d["vasp_cmd"] = self.vasp_cmd d["pot_type"] = self.pot_type d["copy_files"] = self.copy_files d["attempts"] = self.attempts d["stderr_file"] = self.stderr_file d["output_file"] = self.output_file d["poscar"] = self.mat.to_dict() d["steps"] = self.steps d["optional_params"] = self.optional_params return d
[docs]class VaspJob(object): """Construct a VASP calculation job.""" def __init__( self, poscar=None, kpoints=None, incar=None, potcar=None, vasp_cmd="mpirun vasp_std", output_file="vasp.out", stderr_file="std_err.txt", jobname="test", pot_type=None, copy_files=["/users/knc6/bin/vdw_kernel.bindat"], attempts=5, ): """ Define a typical VASP calculation. Args: poscar : Poscar object incar : Incar object kpoints : Kpoints object potcar : Potcar object vasp_cmd : path to vasp executable output_file : standard output file stderr_file : standard error output file jobname : job name pot_type : pseudopotential type copy_files : file(s) to be copied attempts : used in error handling """ self.poscar = poscar self.kpoints = kpoints self.incar = incar self.potcar = potcar self.pot_type = pot_type self.vasp_cmd = vasp_cmd self.copy_files = copy_files self.attempts = attempts self.output_file = output_file self.stderr_file = stderr_file self.jobname = jobname if self.potcar is None: if self.pot_type is None: ValueError("Either pass the Potcar object or provide pot_type") new_symb = [] for i in self.poscar.atoms.elements: if i not in new_symb: new_symb.append(i) self.potcar = Potcar(elements=new_symb, pot_type=self.pot_type)
[docs] def run(self): """Use subprocess to tun a job.""" with open(self.output_file, "w") as f_std, open( self.stderr_file, "w", buffering=1 ) as f_err: # use line buffering for stderr p = subprocess.Popen( self.vasp_cmd, shell=True, stdout=f_std, stderr=f_err ) p.wait() return p
[docs] def write_jobsub_py(self, filename="jobsub.py"): """Write a generic python file for running jobs.""" f = open(filename, "w") f.write( "%s\n" % "from jarvis.io.vasp.inputs import Poscar, Incar, Potcar" ) f.write( "%s\n" % "from jarvis.core.kpoints import Kpoints3D as Kpoints" ) f.write("%s\n" % 'pos=Poscar.from_file("POSCAR")') f.write("%s\n" % 'inc=Poscar.from_file("INCAR")') f.write("%s\n" % 'pot=Potcar.from_file("POTCAR")') f.write("%s\n" % 'kp=Kpoints.from_file("KPOINTS")') line = ( "job = VaspJob(poscar=pos, " + "kpoints=kp,potcar=pot, " + "incar=inc, jobname=" + str(self.jobname) + str(").runjob()") ) f.write("%s\n" % line) f.close()
[docs] def to_dict(self): """Convert the class into a dictionary.""" info = OrderedDict() info["poscar"] = self.poscar.to_dict() info["kpoints"] = self.kpoints.to_dict() info["incar"] = self.incar.to_dict() info["potcar"] = self.potcar.to_dict() info["vasp_cmd"] = self.vasp_cmd info["copy_files"] = self.copy_files info["attempts"] = self.attempts info["output_file"] = self.output_file info["stderr_file"] = self.stderr_file info["jobname"] = self.jobname return info
[docs] @classmethod def from_dict(self, info={}): """Load the class from a dictionary.""" return VaspJob( poscar=Poscar.from_dict(info["poscar"]), kpoints=Kpoints.from_dict(info["kpoints"]), incar=Incar.from_dict(info["incar"]), potcar=Potcar.from_dict(info["potcar"]), vasp_cmd=info["vasp_cmd"], copy_files=info["copy_files"], attempts=info["attempts"], output_file=info["output_file"], stderr_file=info["stderr_file"], jobname=info["jobname"], )
[docs] def runjob(self): """Provide main function for running a generic VASP calculation.""" # poscar=self.poscar # incar=self.incar # kpoints=self.kpoints # copy_files=self.copy_files # cwd = str(os.getcwd()) if self.jobname == "": jobname = str(self.poscar.comment) # job_dir = str(self.jobname) run_file = ( str(os.getcwd()) + str("/") + str(self.jobname) + str(".json") ) run_dir = str(os.getcwd()) + str("/") + str(self.jobname) if self.poscar.comment.startswith("Surf"): [a, b, c] = self.kpoints.kpts[0] # self.kpoints.kpts = [[a, b, 1]] self.kpoints = Kpoints3D(kpoints=[[a, b, 1]]) try: pol = self.poscar.atoms.check_polar if pol: COM = self.poscar.atoms.get_center_of_mass() print("COM=", COM) print("Found polar surface,setting dipole corrections") self.incar.update( { "LDIPOL": ".TRUE.", "IDIPOL": 3, "ISYM": 0, "DIPOL": str(COM[0]) + str(" ") + str(COM[2]) + str(" ") + str(COM[2]), } ) print( "Polar surface encountered in run_job", self.poscar.comment, ) except Exception: pass wait = False json_file = str(self.jobname) + str(".json") print( "json should be here=", str(os.getcwd()) + str("/") + str(json_file), ) print("json should be=", json_file, run_file, os.getcwd()) if os.path.exists(str(os.getcwd()) + str("/") + str(json_file)): try: data_cal = loadjson( str(os.getcwd()) + str("/") + str(json_file) ) tmp_outcar = ( str(os.getcwd()) + str("/") + str(json_file.split(".json")[0]) + str("/OUTCAR") ) print("outcar is", tmp_outcar) wait = Outcar(tmp_outcar).converged # True print("outcar status", wait) if wait: f_energy = data_cal[0]["final_energy"] contcar = ( str(os.getcwd()) + str("/") + str(json_file.split(".json")[0]) + str("/CONTCAR") ) return f_energy, contcar except Exception: pass attempt = 0 while not wait: attempt = attempt + 1 if attempt == self.attempts: wait = True print("Reached maximum attempts", attempt) break # if self.potcar is None: # new_symb = list(set(self.mat.atoms.elements)) # self.potcar = Potcar(elements=new_symb, pot_type=self.pot_type) if not os.path.exists(run_dir): print("Starting new job") os.makedirs(run_dir) os.chdir(run_dir) self.poscar.write_file("POSCAR") else: os.chdir(run_dir) if os.path.isfile("OUTCAR"): try: wait = Outcar( "OUTCAR" ).converged # Vasprun("vasprun.xml").converged # wait=Vasprun("vasprun.xml").converged except Exception: pass try: self.potcar.write_file("POTCAR") print("FOUND OLD CONTCAR in", os.getcwd()) copy_cmd = str("cp CONTCAR POSCAR") self.poscar.write_file("POSCAR") # pos = Poscar.from_file("CONTCAR") print("copy_cmd=", copy_cmd) if ( "ELAST" not in jobname and "LEPSILON" not in jobname ): # Because in ELASTIC calculations # structures are deformed os.system(copy_cmd) # time.sleep(3) except Exception: pass self.incar.write_file("INCAR") self.potcar.write_file("POTCAR") self.kpoints.write_file("KPOINTS") for i in self.copy_files: print("copying", i) shutil.copy2(i, "./") self.run() # .wait() print("Queue 1") if os.path.isfile("OUTCAR"): try: wait = Outcar( "OUTCAR" ).converged # Vasprun("vasprun.xml").converged except Exception: pass print("End of the first loop", os.getcwd(), wait) f_energy = "na" # enp = "na" contcar = str(os.getcwd()) + str("/") + str("CONTCAR") final_str = Poscar.from_file(contcar).atoms vrun = Vasprun("vasprun.xml") f_energy = float(vrun.final_energy) # enp = float(f_energy) / float(final_str.num_atoms) # natoms = final_str.num_atoms os.chdir("../") if wait: data_cal = [] data_cal.append( { "jobname": self.jobname, "poscar": self.poscar.atoms.to_dict(), "incar": self.incar.to_dict(), "kpoints": self.kpoints.to_dict(), "final_energy": (f_energy), "contcar": final_str.to_dict(), } ) json_file = str(self.jobname) + str(".json") f_json = open(json_file, "w") f_json.write(json.dumps(data_cal)) f_json.close() print("Wrote json file", f_energy) return f_energy, contcar
[docs]class GenericIncars(object): """ Construct class containing severalgeneric Incar object. For different psuedopotentials """ def __init__(self, name="", incar={}, pot_type=""): """Intialize with the name of func. and other parameters.""" self.name = name self.incar = incar self.pot_type = pot_type
[docs] def optb88vdw(self): """Select OptB88vdW functional.""" data = dict( PREC="Accurate", ISMEAR=0, IBRION=2, GGA="BO", PARAM1=0.1833333333, PARAM2=0.2200000000, LUSE_VDW=".TRUE.", AGGAC=0.0000, EDIFF="1E-7", NSW=1, NELM=400, ISIF=2, LCHARG=".FALSE.", LWAVE=".FALSE.", ) inc = Incar(data) return GenericIncars( name="optb88vdw", incar=inc, pot_type="POT_GGA_PAW_PBE" )
[docs] def pbe(self): """Select GGA-PBE functional.""" data = dict( PREC="Accurate", ISMEAR=0, IBRION=2, GGA="PE", EDIFF="1E-7", NSW=1, NELM=400, ISIF=2, LCHARG=".FALSE.", LWAVE=".FALSE.", ) inc = Incar(data) return GenericIncars(name="pbe", incar=inc, pot_type="POT_GGA_PAW_PBE")
[docs] def scan(self): """Select GGA-PBE functional.""" data = dict( PREC="Accurate", ISMEAR=0, IBRION=2, METAGGA="SCAN", LASPH=".TRUE.", EDIFF="1E-7", NSW=1, NELM=400, ISIF=2, LCHARG=".FALSE.", LWAVE=".FALSE.", ) inc = Incar(data) return GenericIncars( name="scan", incar=inc, pot_type="POT_GGA_PAW_PBE" )
[docs] def r2scan(self): """Select GGA-PBE functional.""" data = dict( PREC="Accurate", ISMEAR=0, IBRION=2, METAGGA="R2SCAN", LASPH=".TRUE.", EDIFF="1E-7", NSW=1, NELM=400, ISIF=2, LCHARG=".FALSE.", LWAVE=".FALSE.", ) inc = Incar(data) return GenericIncars( name="r2scan", incar=inc, pot_type="POT_GGA_PAW_PBE" )
[docs] def hse06(self): """Select HSE06 functional.""" data = dict( EDIFF="1E-6", NEDOS=5000, ALGO="All", ISPIN=2, LORBIT=11, ISMEAR=0, NPAR=16, LHFCALC=".TRUE.", HFSCREEN=0.2, TIME=0.4, LREAL=".FALSE.", NSIM=4, LPLANE=".TRUE.", NELM=450, LOPTICS=".FALSE.", LMAXMIX=6, ISTART=1, LCHARG=".FALSE.", LWAVE=".FALSE.", ) inc = Incar(data) return GenericIncars( name="hse06", incar=inc, pot_type="POT_GGA_PAW_PBE" )
[docs] def lda(self): """Select LDA functional.""" data = dict( PREC="Accurate", ISMEAR=0, IBRION=2, EDIFF="1E-7", NSW=1, NELM=400, ISIF=2, LCHARG=".FALSE.", LWAVE=".FALSE.", ) inc = Incar(data) return GenericIncars(name="lda", incar=inc, pot_type="POT_LDA_PAW")